Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Should I test cases in which nothing is expected to happen

A Sample can be deleted if status is S or P. I have this tests:

@Test
public void canBeDeletedWhenStatusIsP() {
    Sample sample = new Sample();
    sample.setState("P");
    assertTrue(sample.canBeDeleted());
}

@Test
public void canBeDeletedWhenStatusIsS() {
    Sample sample = new Sample();
    sample.setState("S");
    assertTrue(sample.canBeDeleted());
}

Should I go further? How should I test when the sample can't be deleted? For example:

@Test
public void cantBeDeletedWhenStatusINeitherPNorS() {
    Sample sample = new Sample();
    sample.setState("Z");
    assertFalse(sample.canBeDeleted());
}

Is this test useful? What about the test naming? Would be this logic tested enough?

like image 292
Héctor Avatar asked Aug 19 '16 12:08

Héctor


People also ask

What should you avoid in test cases?

Good test cases avoid a web of dependencies. Dependencies among test cases should be avoided; otherwise, a single failure can show many tests failing, making it more difficult to identify the cause.

When should test cases be created?

Generally, the tester should write test cases early in the SDLC, such as during the requirements gathering phase. Testers should refer to requirements and use case documentation as well as the overall test plan when they write test cases.

Can you write test cases without any document or requirement?

Is it even possible? Well, this may be a pretty rare situation, but such a situation may arise where QA teams are expected to review code changes without being given a functional specification document. Without a testing documents, it's very difficult to follow QA and testing standards and best practices.


1 Answers

SaintThread is giving you a good "direct" answer.

But lets step back. Because you are doing something wrong in your production code. Most likely, your production code does something like a switch on that String that denotes the sample state. And not only once, but within all the methods it provides. And ... that is not a good OO design!

Instead, you should use polymorphism, like:

abstract class Sample {
  boolean canBeDeleted();
// ... probably other methods as well

with and various concrete subclasses, like

class ZSample extends Sample {
  @Override canBeDeleted() { return false; }
// ...

And finally, you have

class SampleFactory {
  Sample createSampleFrom(String stateIdentifier) {
  // here you might switch over that string and return a corresponding object, for example of class ZSample

And then, your tests boil down to:

  1. Testing the factory; example for input "Z", it returns an instance of ZSample
  2. Testing all your subclasses of Sample; for example that canBeDeleted() returns false for an instance of ZSample

The point is: your code does do the work of a FSM (finite state machine). Then don't use if/elses all over the place; instead, do the OO thing: create an explicit state machine. And, free bonus: this approach would also make it possible to turn your Sample objects into immutable thingies; which is most often better than having to deal with objects that can change their state over time (as immutability helps a lot with multi-threading issues for example).

Disclaimer: if your "Sample" class is only about that one method, maybe the above is overkill. But in any other case ... maybe step back and see if my suggestions would add value to your design!

like image 188
GhostCat Avatar answered Sep 30 '22 03:09

GhostCat