Xcode unit test -- setup and teardown only once - ios

Is it possible to setup a unit test class to call setup and teardown methods only once for all the test cases not for each test case?

Actually I found the answer. In order to do class level setup, one needs to implement +(void) setUp and +(void) tearDown. This class methods will be called before any test methods run and after all of the test methods run.

Check this from Apple document

Related

Unit Test case fails when whole Test Suite is executed

I am writing the Unit test cases for my sqlite database class. I have five public API in that class.
My test cases goes something like below:
+ (void)setUp { // Note, this is class method and hence called only once during start of this test suite.
// Code to delete the existing sqlite DB file.
}
- (void)testDBManagerSingletonInstance {
DBManager *dbMgr = [DBManager getSharedInstance];
DBManager *dbMgr1 = [[DBManager alloc] init];
XCTAssertEqualObjects(dbMgr, dbMgr1);
}
- (void)testSaveAndDeleteNicknameAPI {
// Multiple Assert statements in this test.
}
- (void)testAllAccountStatusAPIs {
// Multiple Assert statements in this test.
}
Each of the single unit test is executed without any errors. But it fails when whole test suite is executed.
Probably, I know the Root Cause for failing. It is because when entire test suite is executed then all test runs in parallel and there is simultaneous update-delete happens in the database. Hence, when all unit tests runs it will fail.
But I don't know how can I fix that, because this is not Async, and hence I cannot use XCExpectation class.
Need assistance to resolve & understand the problem.
Tests based on XCTests don't run in parallel - they are run sequentially. To quote the docs :
Tests execute synchronously because each test is invoked independently one after another.
Since you've shown very little code, it's hard to say what is the real problem. It is very likely that you were close with your assumption - you should either improve your setUp (maybe switch to instance version from class version) and tearDown methods or introduce mocks, and perform your tests on a mocked database if possible.
You shouldn't work with singletons in a codebase you want to test. I think that your code uses the sharedSingleton instance of DBManager internally. Each unitest will change the internal state of that instance, all following unitests are therefore corrupted. You need to reset all changes after each test case in teardown.
But my suggestion is to avoid singletons in your base code by dependency injection. When creating an instance of your class inject the singleton instance of your DBManager. That makes unit testing easier. If you inject a protocol instead of an object you may even test your code with a protocol fake implementation.

How to use tests in Xcode (iOS application)

In every new project I see the file with the content (and this file belongs to different target ProjectNameTests):
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// This is an example of a functional test case.
XCTAssert(YES, #"Pass");
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
1) How to use this file?
2) How can I test my application with this file? Why it's better then just launching the application and testing it or then to write test code directly in AppDelegate (when I need to test the responce from server for instance)?
These are called Unit Tests and you can test your components, like classes and functions, with them. You write a Test and if you change something on your classes, the test will show you if the class still works as expected.
For an example: http://www.preeminent.org/steve/iOSTutorials/XCTest/
You should also read a bit about test driven development, it is a nice way of developing and mandatory for most companies.
As a down side on XCode UnitTests i have to tell you that you can't use operations on files within them.
1) To use that file, you replace the testExample and testPerformanceExample with your own methods that begin with test. For example, if you want to test that your Foo class object returns true for isFoo:
- (void)testFooIsFoo() {
Foo f = [Foo new];
XCTAssertTrue([f isFoo], "Foo object should return true for isFoo");
}
2) Why is this better than manual testing? You can write smaller tests for parts that might be more time consuming to reach in the app. It also allows you to test things in isolation. So, rather than test that the network stack works, these kinds of tests are good for testing that you handle data correctly and so on.
Good testing requires a mix of unit testing (which is what this is) and manual testing.
Apple's documentation is light on the why and what you should unit test. But this is a good article from objc.io about testing this way and how to do it with XCTest.
Apple provide a nice documentation. But if you want to see real code, I have a github project that implements tests.
The main purpose ox XCTests is that you can launch tests from Xcode directly without building and running the program. Xcode provide a nice interface to do that.

iOS and XCode: understanding automatic testing

I have created a test project and noticed that XCode generates some test class named: YourProjectName-ProjectTests
This is how it looks like:
- (void)setUp {
[super setUp];
// Put setup code here. This method is called before the invocation of each test method in the class.
}
- (void)tearDown {
// Put teardown code here. This method is called after the invocation of each test method in the class.
[super tearDown];
}
- (void)testExample {
// This is an example of a functional test case.
XCTAssert(YES, #"Pass");
}
- (void)testPerformanceExample {
// This is an example of a performance test case.
[self measureBlock:^{
// Put the code you want to measure the time of here.
}];
}
Would anyone be able to explain me how to use these automated testing methods? Is there an official documentation on this?
Are those test meant to be used as UI testing or as app code testing? Or both?
You an perform UI tests through XCTest but it's designed for unit testing. Instruments has UI Automation which is designed for UI testing.
Opening up XCTestAssertions.h will give you a pretty good reference for what's included in XCTest. Generally all the assertions follow a similar pattern:
XCTAssertSomething(somethingBeingTested, #"A message to display if the test fails");
Hitting ⌘ 5 will bring up the test navigator which lets you run all of your tests, all of your failed tests, or individual tests. You can also run a test by clicking on the diamond shape to the left of the method name in the editor.
Here are a few tips I've come across when unit testing with XCTest:
The last argument in assertions is optional but in some cases it's useful to describe the behaviour you're looking for.
Tests are not run in any specific order, but your tests shouldn't rely on each other anyway.
Mock objects let you test far, far more than basic assertions. I like OCMock.
You can use instruments on your tests for debugging.
Finally, if you have access to another machine you can set up OSX Server to automatically run your tests daily or on every commit and notify you if any of the tests fail.
This is how Unit Testing is implemented in Xcode.
The setUp and TearDown methods are to prepare any mock data necessary to test a unit (which is select part of code).
The two test methods there are just an example. Usually as an author of the unit of code, you know well what the unit supposed to do and what it should not.
Using test methods you test how the assumptions and expectations are satisfied by the unit. The convention is to have a separate test method for each assumption/expectation of a behaviour of the unit.
For example given class that handles strings that has a method to to make all strings CAPS, you would test that passing any random nonCaps string would still return ALL CAPS. An putting none truing as a parameter would return nil or error.
So basically you test your units to behave as expected.
There's a whole theory behind Unit Testing which is out of scope of this thread. Just Google it.

DUnit: 'Global' SetUp and TearDown

In DUnit, SetUp and TearDown are called before (and after, respectively) each test method is executed.
In SetUp, I create an object that loads data from a file. This is slow, especially if I have many tests.
Is there any way to call SetUp once, before executing ALL tests (and obviously the same for TearDown)?
From the documentation:
TTestSetup
TTestSetup can be used when you wish to set up state exactly once for
a test case class (the SetUp and TearDown methods are called once for
each test method). For example, if you were writing a suite of tests
to exercise some database code, you might subclass TTestSetup and use
it to open and close the database before executing the suite.
An an example how to use TTestSetup

Grails withCriteria testing

I'd like to test a "withCriteria" closure and am not sure how to go about it. I see how to mock out the withCriteria call, but not test the code within the closure. When running the test that executes the "withCriteria", I keep getting a MissingMethodException, even though the code runs fine under the normal flow of execution. Any ideas?
Thanks!
Steve
I wouldn't go that route. Instead I'd move the query into the domain class as a static finder method and test it directly in an integration test with real data. Then you can easily mock the helper method when it's called in a controller or service test.
class YourDomainClass {
...
static List<YourDomainClass> findFooBar() {
YourDomainClass.withCriteria {
...
}
}
}
Then in a unit test:
def results = [instance1, instance2, instance3]
YourDomainClass.metaClass.static.findFooBar = { -> results }
This way you test that the query works against the in-memory database in an integration test but it's easy to mock it in unit tests.
Further to Burt's answer, check out named queries as described here:
http://blog.springsource.com/2010/05/24/more-grails-1-3-features/
You can then mock the property/method access in your unit tests as described by Burt.
Since nobody mentioned the option to create a DSL to run other DSLs here's a full disclosure of this method. I use it quite often with very good results.
Groovy/Grails testing DSLs
There's no mock implementation for Hibernate criteria at the present time. You'll need to use integration tests. However, Burt's recommendation of making this a static finder method is a good one for code organization. You should also look at named queries, described at http://www.grails.org/1.2+Release+Notes, for a nice syntax for this.

Resources