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.
Related
I have tests of the form:
expect(ClassA).to receive(:method)
ClassB.perform
Rubocop would prefer if I refactored this to use have_received, which requires ClassA to be mocked. In other words, I need to set up:
allow(ClassA).to receive(:method)
ClassB.perform
expect(ClassA).not_to have_received(:method)
What's the point? Just following the Arrange Act Assert format?
Refactoring to used have_received allowed me to move a lot of the set-up into a before block, and put tests after the action following the Arrange Ace Assert format.
The code noticeably reads better.
I'm learning erlang and I have created a cache_server module implementing gen_server behaviour.
This module is responsible for creating ets tables and has an api to insert, lookup, etc.
I wanted to make test suite for the module and to run test cases for insertion and lookup in one group of tests as a sequence because first function populates the table and other searches for inserted keys.
I tried to call cache_server:start_link([]) in init_per_suite hook function of the suite but in test cases I don't see my cache_server process when I call registered() function.
And I get
{noproc,{gen_server,call,[cache_server,{lookup,numbers,1}]}}
error.
I also tried to move call cache_server:start_link() from the init_per_suite to the first test case but in the subsequent test cases the process gets unavailable.
When I test my code by hands using rebar3 shell, everything works as expected.
Is it possible to share a named gen_server process between test cases in common test test suite?
Try calling cache_server:start_link() in init_per_testcase. As this function is executed before each test case, you would also need to stop the cache_server process in end_per_testcase.
Another option is to group all cache_server related test cases in one group and call cache_server:start_link() in init_per_group and stop the process in end_per_group
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
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.
In my 'notification' model I have a method (notification and contact models both has and belongs to many):
`def self.update_contact_association(contact, notification)
unless contact == nil
notification.contacts.clear
c = Contact.find(contact)
notification.contacts << c
end
end`
that updates the association between a specific notification and contact. It takes a notification object(row) and a list of contact ids. The method works fine, given a single contact id 1 and a notification with the id of 4 updates the table should and will look like this:
notification_id contact_id
4 1
The problem comes in when trying to write a unit test to properly test this method. So far I have:
'test 'update_contact_association' do
notification = Notification.find(4)
contact = Contact.find(1)
Notification.update_contact_association([contact.id], notification)
'end
Running the test method causes no errors, but the test database is not updated to look like the above example, it is just blank. I'm pretty sure I need to use a save or update method to mimic what the controller is doing, but I'm not sure how. I just need the unit test to properly update the table so I can go ahead and write my assertions. Any ideas would be greatly appreciated for I need to test several methods that are very similar/the same as this one.
Tests will generally run any database queries inside of a transaction and rollback that transaction when finished with each test. This will result in an empty database when the tests complete.
This is to ensure a pristine starting point for each test and that tests are not interdependent. A unit test is supposed to be run in isolation, so it should always start from the same database/environment state. It also runs on the smallest amount of code possible, so you don't have to worry about code interaction (yet!).
When you're ready to worry about code interacting, you'll be wanting to build out integration tests. They're longer and will touch on multiple areas of code, running through each different possible combination of inputs so touch as many lines of code as possible (this is what code coverage is all about).
So, the fact that it's blank is normal. You'll want to assert some conditions after you run your update_contact_association method. That will show you that the database is in the expected state and the results of that method are what you expect to happen.