jbehave - How to execute code before each example of a scenario - bdd

When using Serenity with JBehave, my step definition adds information provided through #Given and #When into an internal state class, which is validated in #Then methods.
The state class needs to be reinitialized for each test, that is before each scenario without example and before each example of a scenario with examples.
How can I achieve that?
I found a JIRA ticket requesting #BeforeExample (which would solve my problem) at http://jbehave.github.io/Old_JBehave_Issues/548/. However, using #BeforeScenario clears only before each scenario, but not before each example.
Clearing state in each #Given would not work in the cases where a scenario has multiple #Givens (using Given... And....).

#BeforeScenario does not work (is ignored for scenarios with examples alltogether).
#BeforeScenario(uponType = ScenarioType.ANY) does work, which I found not working before posting this question, but was apparently caused by another reason.
Either way, the method must be public.

You might try to reset scenario-state using JBehave's 'Before' LifeCycle:
Narrative:
...
Lifecycle:
Before:
Given a step that is executed before each scenario
Some additional Lifecycle options:
Lifecycle:
After:
Outcome: ANY
Given a step that is executed after each scenario regardless of outcome
Outcome: SUCCESS
Given a step that is executed after each successful scenario
Outcome: FAILURE
Given a step that is executed after each failed scenario
Source: JBehave Story Syntax

Related

How does Rspec 'let' helper work with ActiveRecord?

It said here https://www.relishapp.com/rspec/rspec-core/v/3-5/docs/helper-methods/let-and-let what variable defined by let is changing across examples.
I've made the same simple test as in the docs but with the AR model:
RSpec.describe Contact, type: :model do
let(:contact) { FactoryGirl.create(:contact) }
it "cached in the same example" do
a = contact
b = contact
expect(a).to eq(b)
expect(Contact.count).to eq(1)
end
it "not cached across examples" do
a = contact
expect(Contact.count).to eq(2)
end
end
First example passed, but second failed (expected 2, got 1). So contacts table is empty again before second example, inspite of docs.
I was using let and was sure it have the same value in each it block, and my test prove it. So suppose I misunderstand docs. Please explain.
P.S. I use DatabaseCleaner
P.P.S I turn it off. Nothing changed.
EDIT
I turned off DatabaseCleaner and transational fixtures and test pass.
As I can understand (new to programming), let is evaluated once for each it block. If I have three examples each calling on contact variable, my test db will grow to three records at the end (I've tested and so it does).
And for right test behevior I should use DatabaseCleaner.
P.S. I use DatabaseCleaner
That's why your database is empty in the second example. Has nothing to do with let.
The behaviour you have shown is the correct behaviour. No example should be dependant on another example in setting up the correct environment! If you did rely on caching then you are just asking for trouble later down the line.
The example in that document is just trying to prove a point about caching using global variables - it's a completely different scenario to unit testing a Rails application - it is not good practice to be reliant on previous examples to having set something up.
Lets, for example, assume you then write 10 other tests that follow on from this, all of which rely on the fact that the previous examples have created objects. Then at some point in the future you delete one of those examples ... BOOM! every test after that will suddenly fail.
Each test should be able to be tested in isolation from any other test!

Grails splitting geb tests

I am new to selenium tests in grails. I am using geb and spock for testing.
I want to split my test plans into some smaller test plans. I want to know if it's possible to make a spec which calls other specs?
What you should do it have a 'Spec' for each area of the application. If that area has more than one scenarios then include them in the 'Spec' that matches that area.
For Example.
LogInSpec
Has a log in scenario.
Form validation scenario.
Log out scenario.
This way things stay organized and its easy to see what sections of your application are failing.
If your goal is to run these in parallel then I recommend that you try and keep tests even across the different test classes. This way they all take around the same amount of time.
You can create traits for each of the modules ,
Exp: consider validations of entering details in form:
Name,Contact details and other comments
Create a trait which has methods to fill these details and verify after saving these details
Use this trait in your spec.
This will make your code more readable and clear
I found now another solution.
I make a simple groovy class:
class ReUseTest {
def myTest(def spec) {
when:
spec.at ConnectorsPage
then:
spec.btnNewConnector.click()
}
In my spec I can call this this like:
def "MyTest"() {
specs.reuseable.ReUseTest myTest = new specs.reuseable.ReUseTest()
specs.myTest(this)
}
I can now use this part in every spec.

Understanding Mutant Failures

I have the following ActiveRecord model class method:
def self.find_by_shortlink(shortlink)
find_by!(shortlink: shortlink)
end
When I run Mutant against this method, I'm told there were 17 mutations and 16 are still "alive" after the test has run.
Here's one of the "live" mutations:
-----------------------
evil:Message.find_by_shortlink:/home/peter/projects/kaboom/app/models/message.rb:29:3f9f2
## -1,4 +1,4 ##
def self.find_by_shortlink(shortlink)
- find_by!(shortlink: shortlink)
+ find_by!(shortlink: self)
end
If I manually make this same change, my tests fail - as expected.
So my question is: how do I write a unit test that "kills" this mutation?
Disclaimer, mutant author speaking.
Mini cheat sheet for such situations:
Make sure your specs are green right now.
Change the code as the diff shows
Try to observe an unwanted behavior change.
Impossible?
(likely) Take the mutation as better code.
(unlikely) Report a bug to mutant
Found a behavior change: Encode it as a test, or change a test to cover that behavior.
Rerun mutant to verify the death of the mutation.
Make sure mutant actually lists the tests you added as used for that mutation. If not restructure the tests to cover the subject of the mutation in the selected tests.
Now to your case: If you apply the mutation to your code. The argument gets ignored and essentially hardcoded (the value for key :shortlink used in your finder does not change depending on argument shortlink). So the only thing you need to do in your test is adding a case where the argument shortlink matters to the expectation you place in the test.
If passing self as value for the :shortlink finder has the same effect as passing in the current argument you test, try to use a different argument. Coercion of values in finders can be tricky in AR, there is the chance your model coerces to the same value you are testing as argument.

How to test order of method calls and redirects in spock unit testing in grails?

I've been seeing some weird behavior with grails controller methods which has had me wanting to create a test case to see if I can reproduce this consistently. So,.. I'll explain the issue first to better understand my question.
I've had some weird behavior recently that when a grails method is called, it sometimes doesn't finish all the method implementation (basically all code goes to server calls) and does the redirect too early. I can see this by my service methods still running but the ui has already (sometimes also incorrectly) redirected wrongly. I've tried debugging through it, but it also leads me to the same places,.. I'll be in a service method but see the page already rendering on the ui. If I could get a good test case going, I feel this may be easier to debug.
Example controller code:
def blam() {
Foo foo = Foo.get(params.id)
String msg = service.method1(foo)
service.method2(foo)
service.doSomething(foo)
redirect(action:"list", controller: "blam", params: [msg:msg, *:params])
}
Example test code: The problem below is that it doesn't actually test a call order at all, I want to test that it is calling the methods in the right order. I have found a couple examples say that you may call multiple then declarations but I dont see a difference if I move the methods around and re run the test.
def "test service call order and redirect"(){
when:
controller.actionMethod()
then:
service.method1(_) * 1
service.method2(_) * 1
service.doSomething(_) * 1
then:
response.redirectedUrl == "bam/list"
}
Any help with how to test this scenario would be greatly appreciated! Also I know it's not the main question but ideas on the redirect are also welcome! (or should I create a different question?)
Cheers!
Use multiple then blocks:
then:
service.method1(_) * 1
then:
service.method2(_) * 1
then:
service.doSomething(_) * 1
The order should be respected then (see http://spock-framework.readthedocs.org/en/latest/interaction_based_testing.html#invocation-order)

How to set the order sentestkit-test runs?

I am using SenTestKit to test an iOS app. I've split tests into methods which run
For example:
In
#interface simpleGameTests : SenTestCase
With tests:
- (void)testFindingFacebookFriends
- (void)testRegisterUsernameFromForm
- (void)testStartGame
It seems kind of random which of the tests that run first, second and third. Is it possible in Xcode to set the order which the tests run?
No. You should write your tests as isolated cases that can be run no independent of each other, no matter the order.
Yes, although the accepted answer is idealistically true and your test cases should indeed be isolated you can set the order in actuality you can control the order and sometimes it is preferable to do so. They are executed in alphabetical order, so testACreateAccount will be executed before testBLoginToAccount. I use this to generate a password in setUp routine then use that in testACreateAccount to setup the account and testBLoginToAccount to test account login using the created one. In this way the test is full and complete (and also no longer strictly a unit test) but it is an invaluable test for my code.

Resources