Archive

Posts Tagged ‘Testing’

Specifying tests

August 6th, 2010 No comments

The latest post on the Google Testing blog is quite interesting. Philip Zembrod discusses the readability of code developed by TDD and found that sometimes reading the test first didn’t always help to understand the written code.

He makes a valid point. I started objecting to using mocks when it was pointed out to me that most of the tests produced with mocks weren’t readable. They typically don’t follow AAA (Arrange Act Assert), and thus work poorly as specifications. But it’s not the mocks, it’s how understandable the test is as a specification. Is it easy to understand what the test does?

If I look at a test 5 months from now, and it is unclear what its testing and how its testing it. Then the ROI of developing that test is lower than it could be.

Tags: ,

Testing on Google AppEngine (Python SDK)

June 28th, 2010 No comments

Testing in Python and Django is pretty straight forward. However I wanted to write tests that assert email sending, URL fetching and other external sources. Making sure the intended code is executed and allowing me to write fuller tests.

These external actions are accessed through Google’s API, and there are some posts about how to test on Google AppEngine.

Here is an example by AppEngine Fan where he uses Mocker to mock out the external API calls. An approach that shows the power of the mocking library, but to my taste it results in too much code, and too much details about the mocking framework in the test making it harder to read. This ties back to a previous post I wrote about testing without Mocks.

What I wanted was some way to keep my original code intact and still have a pretty self explanatory test.

After some more research I found out that all API calls in the Python SDK are done through a proxy map. Allowing you to replace the behavior of AppEngine with your own, stubbed behavior. This method is used in this example (that still uses the mocking framework), and also this post on the user group was that location where I first noticed it.

This made me dig through the source code available in the SDK about how exactly this stub map worked. What I noticed was that if you started using the stub map, you needed to setup all the stubs.

As far as I could tell there was not means to replace just a single stub and let the map remain otherwise intact. Which was a bit of a trouble for me. One of the reasons I researched it was because I didn’t want to have tons of setup code in my tests.

Since my test code is important I thought I’d show how I want my tests to look like.

Requirements for good test-code:

  • Easy to read (Arrange-Act-Assert,Minimal setup code in the test)
  • Fast execution
  • non-fragile (black box testing the most external interface accessible for testing)

I want specific events in JS-Analytics to send an email to the administrators of JS-Analytics. The use case is covered with testing, but I wanted to add a test for this new requirement.

Here is what the test looks like:

    def test_given_a_new_project_an_email_is_sent_informing_the_admins(self):
      request = HttpRequest()
      request.user = User(username="…", user=users.User("…"))
      request.method = "POST"
      request.POST = {"title":"test"}
      index(request)
      self.assertEqual("project created", self.getMessages()[0].subject())
      

As you can see I wish to use the Log pattern for test sent messages. This allows me to check the sent messages in order. There is a method that allows me to access a copy of all sent emails, with their complete structure. Allowing me to assert different aspects of the emails.

To support this I created a base-class that adds the behavior I want as setup code. This setup code is generic and only specific for AppEngine aspects of the code. Here is the structure:

image The base-class called ServiceTest sets up the stub map. I added two stubs that change the behavior from the normal stubs. These add support for setting content that will be accessed through the URLFetch service, and the logging of email messages.

Since no call ever cross the service boundary to actually do anything, the execution time isn’t compromised.

Here is an example of the setContent usage:

    def test_fetching_arrangement_example(self):
      self.setResponse("http://url-to-be-fetched", "fake-content")
      request = HttpRequest()
      result = view_that_does_fetching(request)
      self.assertEqual(result.content, "fake-content")

As you can see its pretty straight forward to Arrange the which content should be returned where.

This structure should be so generic that anyone could use it, so I added a copy of my base-class free to use by others.

Testing without mocking framework

January 12th, 2010 4 comments

I had it pointed out to me at the end of last year that I use Mocks too much. I isolate the class under test more than I might need to do. Isolation of a class has the most value at service boundaries. If other classes can safely be included in the test without side-effects, I’m actually testing more than jus the class under test.

This is a bad thing, right? No. Not necessarily. The tests purpose is to prove that the code solves it’s intended purpose. If by including more of the system that this piece of code interacts with, the test will be more tightly coupled to the actual use of the class.

If I isolate the class, non-API breaking changes in other classes might cause the requested system behavior to fail, but my test which tests the class in isolation will still pass. The purpose of my tests should naturally be to detect defects earlier.

As I considered this I went back to the places in our code-base where I feel TDD has really really helped me. And sure enough, almost no mocking in those tests, relying instead on actual objects. For me, this was sort of an eye opener.

How do I work without mock’s then?

One example is to use inheritance. If I isolate all calls to system-boundaries to a single method, I can inherit from the class under test and override that system-boundary specific piece of code. This allows me create “mocked” version of the class without the need for mocking libraries.

This is called Test-specific subclass. Thank you Patrik!

This method is even applicable to legacy code where mocking isn’t applicable.

Another example would be to use actual objects all the way, if possible. For databases for example you could create a temporary testing database if you have access to a database server. Depending how you access your data you might even be able to have an in memory database instead of an actual database. While this might mean you need to implement a test-class instead of mocking it. If the API doesn’t change all to often it might save you time compared to mocking.

http://xunitpatterns.com/Test-Specific%20Subclass.html
Tags:

Test-list

December 7th, 2009 No comments

Funny thing. Some might remember my how I work with code, where you keep a list of issues you figure out as you work with the code.

Apparently Kent Beck presents this as a pattern called Test List.

I’m trying to embed it below, we’ll see how it goes.

Btw- if this embedding thing is more annoying then helpful, please let me know.

Tags: ,

My testing behavior has changed

December 5th, 2009 No comments

Quite interesting. We just finished an internal TDD course at RemoteX. During it I noticed one thing. How I write tests have changed quite a bit, just over the last few days.

Lately I’ve been doing a lot of testing in JavaScript using QUnit, and coming back from that to testing C# with Rhino Mocks was really an eye opener. One observation, which was also pointed out during to course, is that we use Rhino too much. Simply put, we have a tendency to mock more than we really need too.

Tags:

Testing level + 1

November 30th, 2009 No comments

I learned a new way to test objects the other day.

We had a consultant over to talk about a TDD course he will be holding for RemoteX internally. During the discussion the suggestion to test an object by mocking the object itself came up.

What you do is, you use Rhino mocks (or similar) to create a partial mock of the object under test. What you override is the methods that will result in external communication.

This requires you to put all communication code in a single method, which you then override using the partial mock. The test then becomes, is the method for external communication called.

This reduces the amount of mocking code needed for more coupled objects, and also reduces the “IoC container for testability” need. Allowing the IoC focus to be focused on interchangeable parts.

Tags: ,

Testing JQuery AJAX communication code

November 15th, 2009 No comments

I developed a JQuery Application using TDD these last couple of days. During the testing I used a new technique for testing my AJAX calls, so I thought I’d blog about how I test AJAX calls done by JQuery.

First of you have to see that there are several things to test in just a simple $.ajax call. There is not only all the combinations of the options, there is the behaviour of what to do when the call fails, or is successfull, or times out. There is a boundary between the JavaScript code and the server, will you pass it? Will you test the communication with a server, or even a mocked server using an XML file?

I’ve been testing $.ajax get operations using XML files as a mocked server backend for a while, but recently I mocked it instead.

Mocking $.Ajax requests is quite easy. Before you execute the code that will make the AJAX call, you exchange the ajax function.

$.ajax() = function(options) { options.fail(); };

The above line of codes forces the following ajax calls to automatically execute their fail callbacks. The function can easily be changed to simulate different behaviour of the AJAX requests.

Using this technique there is a risk, that the tests your writing become whitebox testing. The ajax mocking code becomes twins of the code your testing, resulting in a verification that the code is written as is, but not testing that it does what it should do.

Seven habits and unit testing

October 7th, 2009 No comments

Some of the exercises covered in the previous post covered the aspect of analysing the end goal. Now, I’m sure that what we covered was no where near the available exercises. But doing several exercises servers a purpose, even if you already know your goal in life.

Each exercise allows to examine the goals from different angles. If you identify different goals using different angles, then perhaps you haven’t found the right goals, or just more of them. Either how they can increase your confidence in the goals you identify.

Now confidence is what we achieve with unit testing as well. In an way, we can see unit tests as a way to examine the code under test from a different angle. Different compared to the code that will execute the code under test.

Just a thought.

Tags: ,

We need more automated tests

September 14th, 2009 1 comment

During the end of the the 20th century, IBM had a TV commercial that I’m quite fond of. I can’t find it on YouTube, but its quite short. There are two suites talking, one reading a magazine. The one with the magazine says “We need to be on the Internet”, the other asks, “Why?” the first replies “It doesn’t say”.

I’ve seen this approach applied to Software quality several times now.

Allot of managers are hearing good things about automated tests. This results in allot of in house improvement projects trying to solve the question “How can we get more automated tests”.

The problem is that the question is asked all wrong. What the question really should be is “How do we improve software quality?”.

The end result might as well be more automated tests. But if you have a team of developers whom have never worked with testing. Your product isn’t going to be testable, and they will need allot of help. Help to set them up, but first and foremost help to understand why it is important to, not test but, to produce High Quality working software.

Most developers do not believe that there is a problem with their quality of the software. Without getting the team to think about software quality while their working, automated testing will take a long time to get in place. Above all the investment on automated tests will have a longer Return of Investment.

Now automated tests might be a part of the end solution for improving the quality of software, but getting the discussion about software quality going in a well behaved manner can have so much more Return of Investment.

Tags: ,

How I work with code the unit test part

September 10th, 2009 3 comments

I wrote a blog post about how I work with code. The basic idea is that I record actions that I need to take as I work with the code in a format that is readable by the other developers in my team. In case I get run over by a truck they can see where I took off. Also its a way to record what and why I’m doing as I’m progressing through code written by someone else.

I got a response from a former colleague Anna who claimed I wouldn’t need to do it if I had automated tests. Even though Automated tests doesn’t have much to do with personal productivity at first glance, a recording of something that needs to be fixed could be a unit test. If developers run the tests often they are in my shelveset and they can see which pieces of the code I perceive bugs in.

In fact this is exactly what is being done as I work with TDD. Giving support to the fact that TDD can increase the productivity of a developer, following the same ideas presented in Getting Things Done.

Tests however doesn’t record suggestions for design improvements or actions such as “Ask x about icon y”. At Least not as far as I know.

Tags: , , ,