1

We are creating unit test cases for our existing code base, while progressing through the creation of the test cases the test files are getting bigger in size and are taking very long time in execution.

I know the limitations of unit testing and I did some research also to increase efficiency. While research I found one useful idea to tighten up the provided data set.

Still I am looking for some more ideas on how I can increase efficiency of running/creating the unit test cases? We can keep the option to increase the server resources outside of this scope.

Chris Barlow
  • 3,274
  • 4
  • 31
  • 52
Garry
  • 4,493
  • 3
  • 28
  • 48
  • 2
    It greatly depends on how you are testing. Just simple unittests should be able to run several hundred per minute even on moderate hardware. When you throw database fixtures and setup and the like in the mix, execution time rapidly increases. So where is the long execution time coming from? When you know your problem, you can look for a good solution – qrazi Jan 30 '13 at 10:58
  • 2
    If you want to find out which of your tests are slow, have a look at http://cweiske.de/tagebuch/visualizing-phpunit-runs.htm – cweiske Jan 30 '13 at 17:06

1 Answers1

0

As your question was general I'll cover a few of the common choices. But most of the speed-up techniques have downsides.

If you have dependencies on external components (web services, file systems, etc.) you can get a speed-up by mocking them. This is usually desirable for unit testing anyway. You still need to have integration/functional tests that test with the real component.

If testing databases, you can get quite a speed-up by using an in-memory database (sqlite works well with PHP's PDO; with java maybe H2?). This can have downsides, unless database portability is already a design goal. (I'm about to move to running one set of unit tests against both MySQL and sqlite.) Mocking the database away completely (see above) may be better.

PHPUnit allows you to specify @group on each test. You could go through and mark your slower tests with @group slow, and then use the --exclude-group commandline flag to exclude them on most of your tests runs, and just include them in the overnight build. (You can also specify groups to include/exclude in your phpunit.xml.dist file. (I don't think jUnit has this option, but TestNG does; for C#, NUnit offers categories for this.)

Creating fixtures once, and then sharing them between tests is quicker than creating the fixture before each test. The XUnit Test Patterns devotes whole chapters to the pros and cons (mostly cons) of this approach.

I know throwing hardware at it was explicitly forbidden in your question, but look again at @group, and consider how it can allow you to split your tests across multiple machines. Or splitting tests by directory, and processing one directory on each of multiple machines on your LAN. (PHPUnit is single-threaded, so you could run multiple instances on the same machine, each doing its own directory: be aware of how fixtures need to be independent (including unique names for databases you create, mocking the filesystem, etc.) if you go down this route.)

Community
  • 1
  • 1
Darren Cook
  • 27,837
  • 13
  • 117
  • 217