Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it bad form to count on the order of your NUnit unit tests

I have been creating Unit tests like crazy and find that I'm often having to set up something in one test that I just tore down in a previous test. Is it ever reasonable to create something (e.g. a database record) in one test (e.g. an Insertion test) and then use it for a later test (e.g. a Deletion test)? Or should each and every test always stand completely on its own?

Can you even determine the order of tests in NUnit or are they always done alphabetically?

Note: I am specifically asking about the order of tests within one test file. Not across test files or in any way more globally.

Update: Thanks to everyone that answered - there were a lot of good answers and the sense of the group is pretty unanimous. I've chosen John Nolan's answer as he provided the most complete explanation and lots of links. As you may have guessed, I've been sorely tempted to break this rule despite thinking that it might be a bit "smelly" as John put it. Thanks also to Fortyrunner for adding the unit-testing tag.

like image 677
Mark Brittingham Avatar asked Jan 30 '09 23:01

Mark Brittingham


2 Answers

Look into test fixture setups that allow you to specify functions that will be executed before any of the tests in the fixture. This allows you to do common setup once and it will always run, whether you run one test, or all tests in the suite.

like image 60
Tai Squared Avatar answered Nov 15 '22 23:11

Tai Squared


Relying on the order of your tests indicates that you are persisting state across tests. This is smelly

A cleaner way of testing is where you only depend on the single piece of functionality you want to check the behaviour of. Commonly you mock the other objects you need to get your method under test to function.

A good way to think about approaching unit tests is the Arrange, Act, Assert pattern.

Below is a snippet from Karl Seguin's excellent free eBook. I've annoted Arrange, Act and Assert.

[TestFixture] public class CarTest 
{ 
    [Test] public void SaveCarCallsUpdateWhenAlreadyExistingCar()   
    {
         //Arrange
         MockRepository mocks = new MockRepository();
         IDataAccess dataAccess = mocks.CreateMock<IDataAccess>();   
         ObjectFactory.InjectStub(typeof(IDataAccess), dataAccess); 
         //Act
         Car car = new Car(); 
         Expect.Call(dataAccess.Save(car)).Return(389); 
         mocks.ReplayAll(); 
         car.Save(); 
         mocks.VerifyAll(); 
         // Assert
         Assert.AreEqual(389, car.Id); 
         ObjectFactory.ResetDefaults();
    } 
}
like image 28
Johnno Nolan Avatar answered Nov 16 '22 00:11

Johnno Nolan