Category: Blog

  • Sound City: American music, recording, and audiophiles

    Sound City is a documentary about the now defunct, eponymous Van Nuys studios. If you’ve never heard of the studios you’ve almost certainly heard music recorded there. The studios also hosted some of the most famous producers of the last 70 years, many of whom got their start as runners or assistants. The studios operated as a live performance studio: all analog equipment, with the full band recorded simultaneously. Directed and produced by Dave Grohl (Foo Fighters, Nirvana), Sound City is less a tribute to this studio so much as to the unique way in which music was recorded there.

    The studio began with two people who wanted to start a record company and made a $75,000 gamble on a state of the art mixing console. With the room’s acoustics and the quality of the board, it quickly became a premier studio and rode that fame all the way until the boom of CD and digital recording in the late 80s. Business slowed as artists gravitated toward digital until its renaissance in the early 90s with the release of Nirvana’s Nevermind. That resurgence was short-lived, though, and the studio closed in 2011 (selling the famous board to Grohl). While digital recording is not out-right blamed for the studio’s closure, the consequences of its refusal to go digital are front and center.

    Neil Young, one of the first artists to record at Sound City and possibly the biggest critic of digital audio around, is featured prominently and given room to go on his tirade against digital and the so-called “bill of goods” we’ve been sold with the CD and the false sense some musicans today have that they have a studio more powerful than Sound City built into their laptops. Instead of heading into a recording studio and producing an album, an individual can play the same intrument’s part hundreds of times and audition each part individually before stitching together a “prefect” mix.

    This is certainly a disturbing trend, and, more than anything else, that style of recording indeed sucks the soul out of music. But Grohl’s argument is interesting in its technological-agnosticism. Where some would get hung up on technical differences between analog and digital, Grohl focuses on what the art was that studios like Sound City added to the musical process and makes an argument for its preservation. For great artists, Grohl argues, analog or digital doesn’t matter. Great producers can work a compressor whether it’s physically in the room or digitally represented on a screen. There is something intangible about recording music as a band, live, together in one room that adds a soulfulness, cohesion, and sense of mastry over the material that is impossible to reproduce with any other recording method. To the extent Sound City mourns analog recording it is in the way analog forced this style on the process.

    Pro Tools is the easy scapegoat for the anti-digital chorus despite that it did for music what Photoshop did for photography. Professionals might disagree that having amateurs experimenting in their homes is good but for those of us who saw garage bands that might have faded into obscurity record full demos on a two track DAW, it is awesome. You don’t need to be an audiophile to know the difference between a good recording and a bad one. (Bad sound sounds bad, most people are just more tolerant of it.) But when you think you’re in the coolest band since Nirvana, you’re not recording your demo because you know anything about sound engineering, you’re doing it because you want to know something about it. You’re doing it because you want to be in a studio like Sound City.

    The analog-digital debate has a place to illustrate the decline of and call for preservation of a particular recording art form Sound City Studios were particuarly good at and highlights an important lesson about new technology. There are three ways to approach technological changes: fully embrance the new and abandon the old, cling for dear life onto the old and reject the new, or some mix of both. Too many people do one of the first two and neither is productive. Sound City shows us how taking the thrid path is possible, and just as artistic, as either of the first two.

    Sound City Studios will never be forgotten in American music history because of the music that was recorded there. The style and asthetic they infused into the recording process will be carried on by studios and future artists who insist on recording that way. Artists who insist on quality will not be stopped from it by technology. They will, just as Sound City did, focus on the sound of each instrument in the mix with the rest of the band to find the perfect rhythm, timbre, and harmony to produce an album. Dave Grohl’s documentary will live on as a reminder of what recording was like in the early years of the recording industry long after the mp3 has been supplanted by new technology and new musicians using it. To that end, Sound City is an important documentary for the history of American music and the nature of music as a form of art.

  • Retracing footsteps: Bukhansan through Naver

    Most people who know both of us know that my friend Andre and I met on a mountain in Korea. Two Minnesotans (and our significant others) who connected on twitter and decided a hike up one of the South Korea’s most famous peaks, Bukansan, would be a good place to meet for the first time. (Plug: Andre is about to tell a great story about the earliest days he spent in Korea, if you live in DC, you should be there.)

    I was poking around on Naver Maps (Korea’s version of Google Maps) recently and discovered some neat things about Naver Maps. The first is that they have an “air view” feature which is a 360º aerial of different locations around the country. These appear to be taken from some kind of aircraft and so have a slightly more detailed view of the ground than satellite imagery would. Here is a shot of the newly opened George Mason campus in Incheon while it was still under construction. And here is another of our old neighborhood in Ilsan. After poking around a bit on there and eventually finding a great shot of Bukhansan, I decided to turn on Naver’s street view and see how close I could get to the trail head and it turns out you can get all the way to the peak and then follow the street view photos all the way down the mountain allowing me to retrace nearly the entire hike we did back in 2009.
    <!–more–>

    On one hand this is super cool. I even found the little restaurant we ate at on the trail once where our table was a grill placed on a rock in the middle of the river, the spot where we were offered shots of soju as recovery beverages, and the trepidatious steps we had to climb to get ourselves, finally, to the peak. But it does force you to ask why we should have photographic documentation of a trail like that.

    Will there be people, for example, who skip a trip to Korea because they believe that clicking through a street view map is just as good as climbing the real thing? Maybe but things like this make me curious. After reading a New York Times article about the impossibly tough living conditions in Svålbard, Norway I checked out the Google Street View, which in Longyearbyen might as well be called Snow Mobile Trail View. I hope I’m not the only one who discovers there is street view in a place like that and make an instant commitment to find out what it’s like to live there, meet the people who walk (er, snowshoe) those roads every day, and learn about the work they do. Plus, it’s undeniably cool that Naver and Google are putting energy into a task as insane as mapping in photographs all the worlds roads, trails, and byways.

  • Minnesota: The north shore, a giant lake, and a lighthouse

    Wedding Week part two began with a drive from Madison to Minneapolis followed by another drive in the morning from Minneapolis to Castle Danger, an “unincorporated community in Silver Creek Township, MN”, nestled along the shore of the world’s largest freshwater lake, Lake Superior.(1)

    Silver Creek is a short drive north from Two Harbors, MN where we stopped for a bridal hair preview appointment. While Danielle was busy I gave myself a quick tour of the city that birthed one of the world’s most innovative companies, 3M.

    The company originally called “Minnesota Mining and Manufacturing” started in this humble location in Two Harbors.

    By the time we made it to Castle Danger there was just enough light for a dinner over last minute wedding planning. From the decks on our rooms we could see infinite darkness stretching across the lake, and looking up countless stars glimmering above. It was the first of what would turn out to be a phenomenally beautiful weekend on Minnesota’s North Shore.

    The next morning we decided to go for a bike ride. The hotel rented bikes for free and while none of them were bikes I would buy, they were suitable for the 20 mile ride to Split Rock Lighthouse and back. We headed out on the Gitchi-Gami State Trail, a network of 29 complete miles of off-highway bike trail that will one day connect Two Harbors and Grand Marais over 88 miles of bike trail. From Gooseberry Falls onward we rode on one of the newest stretches of trail, stopping along the way to pick agates, visit with boaters, and take in magnificent views of the North Shore.

    A scenic overlook from the Gitchi-Gami Trail near Iona’s Beach Scenic Natural Area, MN.

    It had been at least 15 years since I was last at Split Rock Lighthouse, and had forgotten its importance to the region. It was built in response to a series of wrecks cause by a large storm that hit the lake in 1910 and was a large motivator to extending the road that became Highway 61 up to Split Rock due to its popularity as a tourist attraction. I have to say the station is something to behold. While there we learned that it was built in such a precarious location that all kinds of clever—and dangerous—methods were used to supply the lighthouse and it’s keepers with basic necessities before the road was built. If you pay the admission you can climb the tower and get up close and personal with its Fresnel lens.

    A Fresnel is a type of lens constructed to project a beam of light visible for distances upward of 20 miles. This one is apparently “third order” and the light is officially visible at a distance of 22 miles, though the MNHS reports some fishermen could spot the light from 60 miles north of the station.

    By the time we arrived back in Castle Danger, our guests were starting to
    trickle in and the full wedding weekend really began.

    1. By surface area.

  • Wisconsin: Mud races, free ferries, and small towns

    The first day of Wedding Weekend brought us to Parfrey’s Glen State Natural Area in Southern Wisconsin, the first stop on our Saturday tour. Here, a section of The Ice Age Trail follows a creek bed that has carved a beautiful, fertile canyon that eventually brings hikers to Devil’s Lake. In 2008 a major flood washed out many of the boardwalks and natural walkways that long made up the trail and the beginning of it has since been paved.

    Once we were past the paved and gravel portions of the trail, we found ourselves amidst the serene beauty that is Southern Wisconsin.

    Along Parfrey’s Glen, a mossy wall carved into the ancient creek bed.

    (more…)

  • An open letter to a certain DC driver

    This is just to say,

    You’re right. I did turn left onto N St. from 11th St. NW yesterday. It was not even 8:00 in the morning but there I was, on Brooks Saddle attached to my Surly frame, riding comfortably in the bike lane until about a block before my turn when, signaling as I went, I merged: first into the right lane, then the left, then, finally, into the turn lane.

    Forgive me.

    I have a driver’s license so I know how hard it is to move that right foot from the accelerator all the way to the brakes in order to accommodate slower moving traffic in front of you. And how difficult it must be to see such inferior technology making its way through our city faster than the half ton pickup truck you were driving. Such amazing amounts of energy to go so slowly through an urban area. How much gasoline did you us on your commute yesterday? About a gallon? And there I was impeding you ability to use it more quickly.

    How thoughtless. I deserved to be nearly run off the road by you.

    But honking wasn’t enough for you to tell me how disgusted you were with my choice to make a legal left turn. No, you also had to stop at a green light and slow down everyone behind you so you could verbally let me know exactly how inconvenienced you were. I suppose you would have rather I darted into your lane without signaling. Or perhaps, better, you would have rather I sped up, crossed N half way and ridden in circles around the intersection before running the red light to cross 11th in front of you. That certainly would have made it easier for you to exact your death wish upon me.

    I swear to better reinforce dangerous behaviors in the future.

    Maybe I just have you all wrong, fellow driver, because even yelling at me wasn’t enough for you. No, you had to take it one step further and impersonate a police officer who could “lock me up” for turning left. I wasn’t aware left turning was a jail-able offense but thank you for sparing me, oh wise one. You are just looking out for the law abiding people of the District of Columbia. I assume you also honk and stop to berate every driver who has ever cut off a cyclist, or driven their car without headlights at night or through a snowstorm, or idled in a bike lane, or failed to signal a turn.

    Yes, I judged you all wrong, Driver. You weren’t a rude, snarling human being driving a vehicle 20 times the size of mine but a misunderstood civic activist, making sure that every traveler through DC’s streets is doing so to your liking. I should be thanking you for helping me better understand which vehicles are larger than others. I only wish I could have learned more from you. I hope we can meet again so you can teach me how to properly turn left on a bicycle, or how you might better design our streets to safely accommodate all modes of traffic.

    Best wishes from your favorite cyclist,
    Greg Boone

    Apologies to William Carlos Williams

  • JSON Resume

    A couple years ago my brother turned me on to LaTeX for writing and publishing documents. He’s a math guy and used it for just about everything he did. I’m not sure if he had a working copy of Microsoft Word on his computer, but he definitely had an updated MacTeX. I loved the What You See Is What You Mean philosophy behind TeX and the idea that content was code. I wasn’t a huge fan of how verbose it was both in PDF-generation output and, especially, in the front matter. After writing my first résumé in TeX I thought it was cool how I could write a document style that would show and hide different pieces of it depending on how I output it but, coming from HTML/CSS, everything seemed like it was more difficult than it needed to be. Wouldn’t it be great, though, if there was a way you could keep your résumé data in a standard format, with all the data required to build a full CV or a simple one-pager available when you need it? The JSON Resume project gets that process started. Using a standardized JSON schema, you can generate as complete or simple a resume as you want with a simple
    command: resume export. Check it out at http://jsonresume.org and on GitHub: https://github.com/jsonresume/resume-cli

  • My First Django Project!

    It’s no secret that I’m getting married in August. When the time came to build a wedding website, I saw it as an opportunity to try something new. That opportunity: build my first Django project.

    Prior to this project I had really only worked with WordPress and static site generators. That was fine if all I wanted out of my wedding site was a few pages giving people information about the wedding, but I could get that out of any boilerplate wedding site out there. I wanted more out of my website, and I saw a long list of things it could do, very little of which actually made it into the final product. The biggest thing I wanted, though, was to avoid having 65 tiny pieces of paper coming back to us in the mail to tell us who was or wasn’t coming. I foresaw disaster with things getting lost in the mail (probably would have happened), us losing them (definitely would have happened), and on top of all that, we were just going to manually transfer all that information into a Google Doc anyway. Why bother with the pesky middleman? Our Minimally Viable Wedding-site, then, would include an RSVP app, and I’m proud to announce it is finished, in production, and performing well.<!–more–>

    Why Django?

    Choosing not to stick with WordPress for this project was no small decision. Had we gone with WordPress we could have better integrated with the content on harmsboone.org out of the box. It also would have been easy to distribute as a WordPress plugin. While I haven’t had a ton of experience extending WordPress’s database layer, and I know it has a pretty extensive API for working with your MySQL instance in a safe way, writing this app in WordPress would have meant designing the data structures ostensibly from scratch. With Django, on the other hand, we have a highly flexible and intensely powerful web framework with database extension built right in. It’s been an absolute pleasure to work with and learn how to use it for this project, and I got to learn Python, too, which is a tremendously fun language to use.

    The MTV Pattern

    Django, for the uninitiated, is a Python web framework built upon a Model-View-Template (MTV) pattern (similar to a Model-View-Controller (MVC) pattern). In this way it’s not unlike Rails, Grails, or a litany of other web frameworks out there. The concept is simple. You separate your application into three parts: models, or representations of the data in code; views, methods that prepare data for display; and templates, HTML injected with variables passed from views. Thinking about the application in this way was amazingly helpful in figuring out what data we needed to collect about our guests and how we would use it. We added a hotels model so that we could better determine what kind of transportation we would need to and from the wedding site, and an events model should give us an accurate headcount of who will attend what. Since we didn’t have to mess around with complicated SQL queries, we could write clean, simple data models and quickly extend those models as needed. Here’s all the code we needed to start adding guests to our wedding:

    class Guest(models.Model): # we create a model for a single guest
      first_name = models.CharField(max_length=45, null=True, blank=True)
      last_name = models.CharField(max_length=45, null=True, blank=True)
      attending = models.BooleanField(blank=True)
      primary_email = models.EmailField(max_length=254, null=True, blank=True)
      street_addr = models.CharField(max_length=255, null=True, blank=True)
      city = models.CharField(max_length=255, null=True, blank=True)
      state = models.CharField(max_length=2, null=True, blank=True)
      zip_code = models.IntegerField(max_length=5, null=True, blank=True)
      primary = models.NullBooleanField(null=True, blank=True)
      events = models.ManyToManyField('Event', null=True, blank=True)
      hotel = models.ForeignKey('Hotel', null=True, blank=True)
      bride = models.BooleanField(default=False)
      groom = models.BooleanField(default=False)
    
    class Meta:
      ordering = ['-last_name', '-first_name']
    
    def __unicode__(self):
      return u'%s' % (self.first_name, self.last_name)
    
    

    One of the most powerful fields on a Django model are the foreign key and many-to-many fields which let you relate objects to each other in the database. At first wrapping my head around the distinction among these two was a bit tricky but after a few hours of playing around with it, I was able to structure my models so that they had meaningful relationships where necessary. In the example above, you see there is a ForeignKey relationship between the Guest and Hotel model. This was because each guest could only stay in one hotel (or if they were staying in more than one, we only care about one of them), but many guests could stay in each hotel. For events, however, we knew our guests could attend more than one, so we have a ManyToMany field there. This became especially useful when we made the front-end of the RSVP application. We wanted a way for anyone in a party to be able to RSVP or update their party’s information, but without having some way of relating all of them together, we had no way of knowing which guests were related to any random guest in our system. At the advice of a colleague I created a Party object that would hold some basic information about each group of individuals attending the wedding: who they are, how many of them there can be at a max (it’s +1, not +∞), and whether they have responded. This way, whenever any member of the Snodgrass family RSVPs, all of their data can be updated together, but we can still maintain separate records for each person—not all guests within the same party have the same address, for example.

    South (now Migrations)

    I’m going to say it now: I would have given up on this project were it not for South, a tremendous migration library for Django that, as of 1.7 was merged into core. A crucial missing feature in earlier versions of Django was a way of adding fields to a model after they were initially loaded into the system. If you tried, you would get this strange error saying that that field didn’t exist on the model; of course it didn’t, that’s why I added it! South lets you easily move your models forward by adding the rows in the database necessary to add that field. The coolest part of it is that you get this nice version history of how your models have changed over time. So, it’s really easy to go back to the first migration and say ‘what was I thinking!’

    Django Forms

    I really feel like I only scratched the surface of what can be done with Django Forms. Coming from WordPress I was used to writing my own forms in HTML and validation methods that prepare submitted $_POST data for saving to a database. Django approaches the problem differently. Writing a forms.py file is a lot like writing a models.py file. Each form is a class with a handful of variables and methods that define what kind of data the form should collect and what should be done with them. You can then drop a form into a View and prepare it to display in a specific way before rendering it in a template. In that last step, the entire form can be displayed with this code: `. When the form is submitted, checking that required fields are present and that the data are safe and valid is as simple as thisform.is_valid(). Saving it?form.save()`. Making a form that would add a guests +1 was as simple as:

    if partyForm.is_valid():
      partyForm.save()
    

    That’s it. Django makes some important abstractions in the process of creating and processing forms that helped focus development on how the data need to change.

    Next steps

    I’d like to refactor the views to take advantage of class-based views. One of the guiding principles of Django development is strict adherence to the DRY principle (Don’t repeat yourself). There is way too much repeating myself going on in this app. All but one view in the RSVP app starts with pk = request.session.get('pk') and guest = Guest.objects.get(pk=pk) and passes a global variable ‘bride’ and ‘groom’ to each view. This is super annoying! Django’s class based views should help me get passed that, but there wasn’t room for it in this release.

    Another thing that needs done is to split the RSVP app into it’s own project and make it installable with pip. It’s currently bundled in a repo with the Posts app which is ostensibly a clone of the tutorial’s blog app and a bunch of Django configuration crap that you wouldn’t need if integrating it with an existing Django project. There are also way to many static assets hard-coded into the CSS and template files. I’ll want to make those a bit more modular and perhaps even rewrite the CSS in less before it’s ready for reuse. All in all, though, it’s basically ready to go if someone else wanted to use it in their wedding website.

    Future versions of the app might also include a table manager, so someone could design their seating charts through the Django admin, and food options (our wedding is a buffet, so you get no choice on the RSVP). I’d also be keen on some design pull requests. I’m clearly not a very imaginative visual designer and while the CSS here isn’t bad, it could use a little love.

    Let’s face it, the list of what can go in a wedding website is unending. But this is a good baseline for building any of it.

    In the meantime fork the project on GitHub!

  • Flannel: A Python Project

    I’m a big fan of learning new things in programming. It’s part of
    why I tried running this blog on a static site generator only to get scared back onto WordPress, and why I’ll probably give SSGs another shot before swearing them off completely. I recently had the opportunity to work on a project in Python for work (in addition to a WordPress plugin) and it was an absolute thrill.

    The Problem:

    My client had a rather large WordPress site that relied on a home cooked theme, a few internally developed plugins, and a few plugins from the WordPress Plugin Repository. We also have a process for upgrading those plugins and WordPress core that is a bit more complicated than just hitting the ‘upgrade’ button in wp-admin. We also have a lot of users, not just registered users, but people who visit our website, too, who do not want the site going down, stop working, or unexpectedly changing dramatically. That is, we’re not facebook, we prepare our users for changes to their user experience. We had to maintain all those things but also make the deployment and upgrade process easier, faster, and less prone to human errors.

    (more…)

  • How can I Configure WordPress to Handle Dynamic Hostnames?

    An increasingly common problem enterprise-level WordPress installations will face is how they handle build, staging, and production environments where IP addresses inside a VPN use a different hostname to access the same server as those outside the VPN. In this case, the wp-config.php file is a little more complicated than in the famous 5-minute install.

    It’s somewhat common practice now to lock WordPress’s site URL setting in code rather than in the settings menu. Mostly people do this because it is good insurance that nobody will ever change them but at my client we do it so that local environments, and our private and public servers can all share the same wp-config. We did it, fairly standardly, with the HTTP_HOST key from the $_SERVER superglobal. It’s pretty neat and makes life really easy.

    We ran into a problem with our unified wp-config this week when a new load-balancing and proxying environment caused ‘HTTP_HOST’ to point at an inaccessible address in some environments. What to do?

    The proxy was ferrying our visitors around using a standard called X-Forwarded-For (XFF). If the user was coming from outside the VPN, their request would be forwarded through to the correct location. Simple enough but, because the requests are all pointing to an internal hostname, HTTP_HOST was resolving to an address inaccessible to the user and thus all our static assets were unable to load. The problem turned out to be easy to solve.

    As it turns out an X-Forwarded-For is often accompanied by an X-Forwarded-Host (the hostname the user was trying to reach). We simply sniff out whether $_SERVER has a X-Forwarded-Host key and set site_url and wp_home to the X-Forwarded-Host and fall back on HTTP_HOST for non-forwarded environments. Something like this:

    if ( array_key_exists( "HTTP_X_FORWARDED_FOR", $_SERVER ) ) {
        define( "site_url", $_SERVER["HTTP_X_FORWARDED_FOR"] );
        define( "wp_home", $_SERVER["HTTP_X_FORWARDED_FOR"] );
    } else {
        define( "site_url", $_SERVER["HTTP_HOST"] );
        define( "wp_home", $_SERVER["HTTP_HOST"] );
    }
    
  • Markdown&#58 It’s not for everyone

    Interesting perspective from Tom McFarlin on Markdown as a choice, not a default. He gets at an underlying issue of my struggle to fully adopt a static site blog where Markdown, with HTML as a fallback, is the default mode of entry.

  • Writing Integration tests in WordPress

    Integration testing, like unit testing, is a best practice with the goal of evaluating a piece of software’s ability to interface with the rest of a system. Earlier I elaborated on the distinction between integration and unit testing and I won’t repeat myself here. Instead I’ll briefly expand our definition of integration test and demonstrate how to use the WordPress Unit Test Suite to test a plugin.

    What’s an Integration Test?

    Tests which execute your code directly to determine if it properly interfaces with its dependencies are called integration tests. They require the greater system be installed in order to verify where a failure might occur. Unlike unit tests, integration tests do not necessarily test the correctness of your code as much as they do the system’s stability and your code’s interaction with it. For example, if we’re building a method to save data passed through a POST request into a database, a unit test would demonstrate that our method prepares that data appropriately and calls the correct methods for saving the data. An integration test would actually instantiate the database and save the record. For this reason, integration tests are more expensive. You’ll recall that the WordPress Unit Test Suite (WUTS) requires a dedicated MySQL database and a working copy of WordPress in order to execute tests. Reading and writing from MySQL can be an intensive process.

    For a plugin we are developing at my client, we had five tests that verified a feature. With WPUTS, the tests took nearly 42MB of memory out of our server, when we tested the same feature with unit tests, we shaved it down to 8, about a 5.25x improvement. The unit tests might be faster, but the data gleaned from an integration test is valuable in its own right. How else do you evaluate why a plugin fails when all of its unit tests pass? Perhaps it’s because you are sending the wrong data to the methods you’re mocking. Integration tests will catch that, unit tests won’t.

    How to do it

    First install WP-CLI as it will make everything much easier. The directions on getting the plugin tests initialized through WP-CLI are very clear and I won’t repeat them here. This will install a separate copy of WordPress and a separate database for testing. If you run phpunit from your root directory, you should output similar to this travis build. Passing tests validate the stability of WordPress, the failing and skipped tests are either incomplete or anticipate features in development. The tests will probably take under two minutes to execute depending on your system. If you cd into wp-content/plugins/your-plugin you should see a tests directory, a phpunit.xml file, and a bootstrap.php inside the tests directory. Run phpunit from your plugin’s root directory and it will execute any files which begin with ‘test-‘ and end with ‘.php’. Go ahead and create a test-your-plugin.php file inside the tests directory.

    ProTip:To change which files phpunit will pick up when you run it, modify the bootstrap.php file.

    Your first test

    As we did with unit testing, let’s start with a simple test we know will always pass. You’re going to want to first extend the WordPress unit test suite:

    class YourPluginTests extends WP_UnitTestCase {

    }

    Then inside that class, write a simple test:

    function testIsAlwaysTrue() {
        // Arrange
        $foo = true;
    
        //Assert
        $this->;assertTrue($foo);
    }

    `$foo` will always be true and that test should pass if you run phpunit. Now let’s take a look at some of the features the WPUTS has to offer.

    The factory

    WPUTS has a factory for creating things you might need for your tests. Let’s say we’re writing a method to check the title of a post. Since we have none, WPUTS should create one for us. Let’s write a test that checks if a newly created post has a title.

    function testPostHasTitle() {
        // Arrange
        $post_id = $this->factory->post->create();
    
        // Act
        $post = get_post($post_id);
    
        // Assert
        $this->assertTrue(!empty($post->title));
    }

    That’s a fine looking test, and it passes! But what does it tell you? Does it verify the `get_post()` method? In some ways it does, but it certainly doesn’t verify all of `get_post()`. In this case it mostly verifies that a post can be fetched out of the database. Let’s take the same method [we verified earlier][4] and write an integration test for it, only this time we won’t mock it. We’ll start with the same name:

    public function testTestPostExpectsMetaDataSaved(){
    
    }

    In our arrange section we’ll use the factory to create a post, and we won’t do any mocking. Remember, we’re interested in whether the system is functioning with our code in it. Our arrangement, in this case, will also include a variable `$expected` we will use in the assert section. The act section will be mostly the same, and the assert section will contain a check to `get_post_meta` and an `assertEquals` statement compairing $expected and our result. If all is well with our `save_meta_data` and the WordPress methods used in it, they should be the same. We can also write a message to print if the test fails.

    // arrange
        $post_id = $this->factory->post->create();
        $expected = 'New meta value'
    
        // Act
        $methods = new MetaMethods();
        $methods->save_meta_data($post_id);
    
        // Assert
        $actual = get_post_meta($post_id);
        $this->assertEquals(
          $expected,
          $actual,
          'Meta data expected to equal ' . $expected . ' but instead was ' . $actual);
    

    If we run the test now, it will either fail or error out because we haven’t written $methods->save_meta_data yet. Our development goal: make the test pass. Once this test passes, we can say, with a bit more certainty, that our method saves meta data properly.

    Unit and integration testing are similar but one distinct advantage of integration testing is that we can use the testing environment to experiment with core WordPress functions. We can use it to get under the hood, as it were, without digging through the codex and StackOverflow. If your unit tests are passing but your plugin isn’t working, try running an integration test and see if maybe you’re not feeding the mocked function the proper data.

    Testing of any kind allows you to think carefully about what your method should do and how to make it happen. Do you need a full post object, or do you need only the ID? Do you need all those conditionals? How much work is this method actually doing? The more you test, the simpler your code will be. Simpler code is easier to test, troubleshoot, and extend. It is important, however, to be mindful of the differences between the two concepts as they have implications for what you can and can’t say for certain about your code.

    As before, our full test is below:

    class YourPluginTests extends WP_UnitTestCase {
        function testPostHasTitle() {
            // Arrange
            $post_id = $this->factory->post->create();
    
            // Act
            $post = get_post($post_id);
    
            // Assert
            $this->assertTrue(!empty($post->title));
        }
    
        public function testTestPostExpectsMetaDataSaved(){
            // arrange
            $post_id = $this->factory->post->create();
            $expected = 'New meta value'
    
            // Act
            $methods = new MetaMethods();
            $methods->save_meta_data($post_id);
    
            // Assert
            $actual = get_post_meta($post_id);
            $this->assertEquals(
              $expected,
              $actual,
              'Meta data expected to equal ' . $expected . ' but instead was ' . $actual);
        }
    }
  • Using Composer to Manage a WordPress Installation

    The team at Roots.io have a fantastic walkthrough of Composer and why and how you should use it in managing a WordPress site. Composer is a wonderful piece of technology that reduces the headache of figuring out how to managing the individual components of your site to a single file and software solution. With WordPress, a utility like composer breaks an installation into discrete pieces. This allows you to automate deployments and updates of your site using only the composer.json file and isolating each part of your site to its own maintainable place. I plan to make composer-automated installations the default on all future WordPress projects I undertake.