Archive for the 'Testing' Category

Testing View Controllers

I have been writing tests around my iPhone apps’ view controllers in order to follow the same TDD practices we use in other environments. Writing tests first has changed the way I structure my code in a couple of ways which I think offer immediate and emergent benefits for my applications. Most of an iPhone application’s business logic is implemented in its view controllers. Testing those controllers is therefore a priority if I want to have a well tested application.
Below are some examples of the sort of tests I have written for my view controllers using GTM, Hamcrest, and OCMock (our iPhone Unit Testing Toolkit). Hopefully this can serve as a starting point for the tests you could be writing for your own projects.
Continue reading ‘Testing View Controllers’

Javascript Testing Talk in Oakland

Next week at EBig Jonah and I are wrapping up our world tour of talking about Javascript testing. March 17th in Oakland: ”Recent evolutions in Javascript testing frameworks now allow creating test suites, test-driving development, and running tests on a continuous integration server. This allows us to support more complex Javascript, have confidence in the implementation, and push more of the logic from the server into the browser, reducing the load on the server.” The focus of the talk is walking through a suite of tests we build for a real-world example.

For those of you who caught it last week at the SDForum, here are the links people requested:

To sign up for next Wednesday, go to the EBig site.

Test-Driven JavaScript with ScrewUnit and BlueRidge

Jonah and I are taking our presentation about Javascript Testing on the road next Tuesday at 6:30 in Palo Alto, at the SDForum

The teaser for it… Recent evolutions in JavaScript testing frameworks now allow creating test suites, test-driving development, and running tests on a continuous integration server. This allows us to support more complex JavaScript, have confidence in the implementation, and push more of the logic from the server into the browser, reducing the load on the server…

Hope to see you there.

Screw.Unit JS Testing in Maven: javascript-test-maven-plugin

I’ve written a maven plugin to integrate Screw.Unit javascript tests into a maven build. The project is inspired by the Blue Ridge testing framework for Rails, but it’s a bit more light-weight by design.
Continue reading ‘Screw.Unit JS Testing in Maven: javascript-test-maven-plugin’

Unit testing JavaScript with Blue Ridge

My current rails project is using Blue Ridge and the tool set it bundles together (Rhino, env.js, Screw.Unit, and Smoke) to write test driven JavaScript. The ability to write tests of my JavaScript, in JavaScript, as efficiently as I can test other languages has forced me to rethink how I structure my work and I’m writing better code because of it.

There are a couple of different options for JS testing available at this point but Blue Ridge’s plugin is the first I have seen which made writing test driven code as easy as I have come to expect while still providing all the functionality I need. In particular;

  • Running my tests in a browser is fast. Refreshing fixture pages to rerun tests is dramatically more efficient than waiting for selenium tests to cycle.
  • I can debug my tests as they run against their fixtures pages and inspect or manipulate the DOM at any point.
  • I have mock and fake objects available to test behavior and stub out dependencies.
  • My JS tests run in continuous integration, just like all the other tests.

By writing fixtures pages and tests first I am immediately using all of my code in two locations and running it against slightly different DOMs. That has pushed me to encapsulate most of my code as jQuery plugins and think carefully about how much I depend on the page’s structure. I end up with terse selectors instead of using whatever attributes are readily available and a clear configuration point for my page’s behavior as I chain together plugin calls in $(document).ready().

We’d like to see what other developers have done and share what we have learned so far so Carbon Five is hosting an open discussion of JavaScript testing in our office this week.

Topic: Javascript Testing
When: Tuesday Nov 17
6pm: arrive/network
6:30 – 8 presentation and discussion
Where: Carbon Five office: 171 2nd Street, 4th Floor

Please RSVP if you would like to attend.

C5 Test Support new addition: FunctionalTestRunner

We’re always looking for new ways to test our applications and we’ve been trying a few new things on our projects. One of the recent additions is a JUnit test runner designed to help make writing and running functional tests easier. In Javaland, we use Selenium and/or HtmlUnit for our functional tests. These are the tests that run against a deployed application over the wire using a real or simulated browser. Most of our functional tests work the application in the same way a real user would, testing sequences of realistic activity and often touching a number of pages. Since our functional tests use either a real browser or a simulated one, Javascript is executed and assertions made on the results. This gives us greater confidence that our app is really working, end to end.

Here’s the high-level flow that the functional test runner provides:

  1. Load fixture data from a DBUnit dataset.
  2. Download and install the application server (if necessary).
  3. Start the application server (using Cargo).
  4. Deploy the application, waiting until it’s completely started.
  5. Run one or more functional tests (using your preferred testing framework – Selenium, HTMLUnit, etc)…
    If a test dirties the database in a manner that must be reset, the test class can be marked with the @DirtiesDatabase annotation. This will reload the database fixture and optionally restart the application.
  6. Shutdown the application server.

Continue reading ‘C5 Test Support new addition: FunctionalTestRunner’

Web Application Testing @ SDForum October 6th

Updated: Added links to presentation and source code.

I’ll be down in Palo Alto speaking about Automated Web Application Testing Tuesday October 6th. If you’re interest in getting a peek at the typical Carbon Five Java web architecture along with a variety of strategies and techniques for testing, c’mon down and join us. The session will be primarily code-driven. I’ll implement a few features along with unit, integration and functional tests and show off some of the techniques and custom tools that help keep things simple and easy during development. Some of the topics include:

  • Brief overview of our typical web architecture and tools stack
  • Differences between Unit, Integration and Functional Tests
  • Dealing with the database (schema and fixtures)
  • Where does test coverage pay off the most?
  • In-browser and out-of-browser functional testing
  • Carbon Five best practices, custom tools and techniques
  • And more…

You can find the gritty details on the SDForum site.

Doors at 6:30 and the show begins at 7:00. Hope to see you there!

Here are the artifacts from the presentation:

Custom Xcode Templates for iPhone Development

Previously we discussed building an iPhone Unit Testing Toolkit. I wanted to reuse that work without having to repeat those configuration steps every time I started a new Xcode project. Xcode provides a number of templates or starting iPhone applications so I made my own versions which include all of the unit testing tools we rely on.

Continue reading ‘Custom Xcode Templates for iPhone Development’

assert_changes and assert_no_changes in Ruby

Update: This code and documentation is now available on github: http://github.com/ndp/assert_changes/tree/master

The Problem

On our work on gobalto.com, we spend time to have good fixture data for our tests– data that can represent all the important application states that our tests require. As a result, our tests are very dependent on the data. It’s important that someone doesn’t inadvertantly change it in subtle ways. This has led us to write not only asserts at the end of tests, but pre-conditions as well. For example,

    ...
    inotech = companies(:inotech)
    assert inotech.services.public.include?(categories(:a))
    assert inotech.services.public.include?(categories(:b))
    assert inotech.services.public.include?(categories(:c))
 
    post :edit_services_dialog, :id=>inotech.id,
                                          :service_category_id=>categories(:a).id
    inotech.reload
 
    assert inotech.services.public.include?(categories(:a))
    assert !inotech.services.public.include?(categories(:b))
    assert !inotech.services.public.include?(categories(:c))

Although the pre-conditions were introduced to guard against accidentally changing fixture data (or just to figure out what’s going on), we don’t necessarily delete them. They provide stronger tests. And in some ways, leaving in pre-conditions make the code more readable by providing documentation of your assumptions to the readers. The code above would be hard to follow without the clarifying pre-conditions. What do we expect to change and what stays the same?

Unfortunately all these asserts make the tests twice as long. And there’s a subtle readability problem: there’s no relationship between the corresponding pre- and post-conditions. In the example above, you have to scan carefully to see that the three assertions are repeated, but negated (b and c only). The reader must mentally put pieces together. And it’s not DRY. Using local variables doesn’t help much.

The Solution

I was inspired by a nice little test helper called assert_difference. It takes a string to evaluate and a block to execute. It’s useful for checking on state changes– especially database changes– during a test:

assert_difference('Company.count', -1) do
    Company.delete_one
end

(Without this method, we rely on a count of all database records, or merely look for specific ones. The former approach leads to brittle tests, and the latter to incomplete assertions.)

A limitation of assert_difference is that it only deals with integers. What if it were generalized? Here goes:

    i = true
    assert_changes 'i' => false do   # read as: i changes to false
      i = false
    end

Continue reading ‘assert_changes and assert_no_changes in Ruby’

Custom Constraints for OCMock

In my last post on unit testing iPhone development I introduced a couple helpful tools including OCMock, a mock objects implementation for Objective-C.

I recently came across a scenario where I needed to make an assertion on an argument passed to an expected method invocation but OCMock did not provide the constraint I needed. I was testing a FileDetailsViewController that pushes a new FileContentsViewController on to the view stack when a button is pressed. I mocked the UINavigationController so that I could add an assertion that pushViewController:animated: is called with the right arguments.

The meat of my test is:

@interface FileDetailsViewControllerTest : SenTestCase {}
    FileDetailsViewController *controller;
    id navigationController;
@end
 
@implementation FileDetailsViewControllerTest
 
-(void) setUp {
    controller = [[FileDetailsViewController alloc] initWithNibName:@"FileDetailsView" 
                                                             bundle:nil];
    navigationController = [OCMockObject mockForClass:[UINavigationController class]];
    controller.navigationController = navigationController;
}
 
-(void) testShowContentLoadsView {
    [[navigationController expect] 
         pushViewController:[OCMConstraint isKindOfClass:[FileContentsViewController class]]
                   animated:YES];
    [controller showContentsButtonWasPressed];
}
 
-(void) tearDown {
    [navigationController verify];
}
 
@end

Note that in this example, I some fanciness is required to assign controller.navigationController = navigationController since it is a readonly property in the UIViewController API. I’ll explain what I did in a later post.

The OCMock feature I was missing is the OCMock.isKindOfClass constraint. So I wrote my own.

Following is the header file that declares the isKindOfClass assertion as a static method in an Objective-C category for OCMock. Categories are kind of like Ruby mixins for Objective-C. You can add static or instance methods to an existing class definition. With this approach I can follow the OCMock pattern of providing static factory methods on the OCMock class for the range of constraints available.

//File: OCMockConstraint+Extensions.h
#import <OCMock/OCMConstraint.h>
 
@interface OCMConstraint (Extensions)
 
+ (id)isKindOfClass:(id)value;
 
@end

Following is the implementation, both of my new constraint and the factory method to create it.

//File: OCMockConstraint+Extensions.m
#import "OCMockConstraint+Extensions.h"
 
@interface OCMKindOfClassConstraint : OCMConstraint
{
    @public
    id testClass;
}
@end
 
@implementation OCMKindOfClassConstraint
 
- (BOOL)evaluate:(id)value
{
	return [value isKindOfClass:testClass];
}
 
@end
 
// Static factory method
@implementation OCMConstraint (Extensions)
 
+ (id)isKindOfClass:(id)value {
	OCMKindOfClassConstraint *constraint = [OCMKindOfClassConstraint constraint];
	constraint->testClass = value;
	return constraint;
}
 
@end

This implementation shows both how to write a custom constraint for OCMock and a use of Objective-C categories to provide a nice API for using it.

In many cases, you’ll want to write a custom constraint that is specific to your test scenario and not appropriate to be shared globally in this manner. In this case you’ll probably follow a similar strategy but implemented in your test class instead of mixed in to OCMockConstraint.