0

I have a basic class in C# from which I create inherited classes for databinding scenarios. You can think of it as a substitute for .NET's DataRow class.

I want to automate testing of a typical row's lifetime, making sure that things such as object state and changes detection remains coherent throughout.

My first thought was to simply use unit test class with a method that would do multiple operations and consequent assertions, like this:

/*
For the sake of keeping this as simple as possible, let's just assume
that new instances can be created with a public constructor, as "unchanged".
*/

var row = new PocoTest(); // Derived from aforementionned base class

Assert.AreEqual(RecordStates.Unchanged, row.RecordState);
Assert.IsFalse(row.IsPropertyModified("MyProperty"));

row.MyProperty = "this is a new value";

Assert.AreEqual(RecordStates.Modified, row.RecordState);
Assert.IsTrue(row.IsPropertyModified("MyProperty"));

row.AcceptChanges();

Assert.AreEqual(RecordStates.Unchanged, row.RecordState);
Assert.IsFalse(row.IsPropertyModified("MyProperty"));

However, this doesn't feel right in the unit testing paradigm in which it is recommended to have only one thing at a time being tested.

So I'm kind of looking for some advice, here. Am I overthinking this? Should I just keep doing it this way? Or is there another, better and more adapted way to accomplish something like this?

2

Remember many rules in programming are essentially recommendations you can follow. So sometimes this is acceptable.

Unit tests are called that way because they focus on testing single units of work. Generally, if you need more than one assertion per test case, you are

  • structuring your test inappropriately.
  • testing alternative code flows in the method, which are recommended to be tested with a separate test.
  • your method does too much and should be broken down.

I would break down your test into 3 tests, and name them appropriately. Next time you have 3000 unit tests in your system and one of them fails during automation build, you wouldn't see "TestRowLifeTme" Failed. You will see: "TestRowSetValue" failed, which is way more useful and specific.

  • The problem is that I can't seem to find a way to keep individual tests in a precise order, nor maintain object state in between them. I'm sure it's because it's not meant to be used like this (after all these are unit tests). However, that doesn't make the need to test functional flow any less relevant. So what should I do? Is there some other tool that's more appropriate for that kind of scenario? – Crono Jul 3 '15 at 17:31
  • You are right, these are unit test and order should not matter as well as state should not be persisted. generally in unit tests, you want to simulate certain condition and then test against it. You would need integration tests if you are trying to test the flow of event, etc. stackoverflow.com/questions/4904096/… – Alexus Jul 3 '15 at 17:32
  • So, you have any suggestions for functional flow testing? Right now I'm considering console app projects. I just hate that it won't be automated / integrated in Visual Studio's test runner. I hope something better exists. :s – Crono Jul 3 '15 at 17:35
  • Generally, you should have both. Console app can be automated in post build events of your project. But I would focus on unit tests first and isolate each scenario. That way you need way less integration tests. – Alexus Jul 3 '15 at 17:36
  • 1
    @Crono: You could also build your integration tests similarly to these current tests, but since your unit tests will test each step, you only need to assert on the final state. It's not really a bad tool for the job, but I'd build a separate integration test project perhaps. Also, nice name. – Magus Jul 3 '15 at 19:17

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.