Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Protractor/Jasmine Conditional Test Cases

Related to this question: How can I create conditional test cases using Protractor? -- I'm curious whether there is a legitimate (documented) answer to these scenarios, because I can't get a straight answer.

While the ignore solution posted in the linked question works, stylistically I'm not a fan of it. At first glance it just looks like you're ignoring/skipping the spec.

Additionally, I asked this question on Gitter - Is the following code bad practice?

if(questionAnswer == "Yes") {
   it('should display another question', function() {
       // code
   });
}

The answer I received on Gitter from someone on the Protractor team was rather vague:

this might lead to flaky tests... I don’t think there’s anything that says it is not bad practice. If it is working for you, then run with it.

I'm not satisfied with that answer because he started with "might be flaky"... which doesn't sound stable to me. The only alternative I see is to create the conditional inside the spec as normal, and create an arbitrary assertion to capture the else scenario, i.e.:

it('should display another question', function() {
    if(questionAnswer == "Yes") {
        expect(question2.isDisplayed()).toBe(true);
    }
    else {
        expect(true).toBe(true);
    }
});

But then I'm automatically adding an additional test case, when it's only needed 50% of the time. I know it's a small issue but it really bothers me.

The above code is the scenario I'm currently facing - If the last spec answered "Yes", I need to run an additional spec for the next question. If not, that's the end of my tests. Is there really no official way to conditionally run a spec in Jasmine/Protractor?

like image 673
Gunderson Avatar asked Jun 10 '16 12:06

Gunderson


1 Answers

In these situations I use what's called a context. Typically a context is used to denote a state change that affects the behavior of the code you're testing.

While not explicitly available in Jasmine, they do exist in other BDD-style testing frameworks like Rspec (related reference). Often, context is just an alias for describe.

So in Jasmine, I will use describe and structure my test as follows:

describe('someMethod', function() {
    describe('when a privileged account', function() {
        beforeEach(function() {
           questionAnswer = "Yes";
           someMethod();
        });

        it('should do something', function() {
            // expectation
        }
    });

    describe('when not a privileged account', function() {
        beforeEach(function() {
           questionAnswer = "No";
           someMethod();
        });

        it('should do something else', function() {
            // expectation
        }
    });
);

I avoid "conditional tests". I'd rather run more tests to ensure I've exhausted all the code paths. In addition, I find the tests are more readable which is one of the goals of BDD-style testing.

Finally, adding logic to tests is one reason why people go down the absurd path of testing your tests. Then testing your tests that test the tests. and then...

like image 60
Jason McCreary Avatar answered Oct 13 '22 20:10

Jason McCreary