XCTest test failing, with no code in body - swift

I am trying to create unit tests for my framework. I've created a 'Unit Testing Bundle' target and have my test class compiled in the target.
My test class extends XCTestCase.
I've left func testExample() empty, but still the test is failing. Why is this?

Related

Can I reset private static variable or reset application from XCTest code?

I am testing a framework.
Every test case set static variable and it looks like XCTest shares static area of a framework.
As a result, running tests at the same time makes test failure from the second test.
Note that running tests individually makes all test succeed.
I am testing with Unit test not UI test, but should I reset App at the stage of class tearDown()?
If so, please tell me how to do it, because
XCUIApplication.terminate() fails in the subclass of XCTestCase.
I am using Xcode 11 Swift 5.1
I believe what you're looking for are the instance methods, not the type methods.
Furthermore, consider setUp over tearDown:
Here is the description for the instance method setUp from Apple's documentation:
Before each test begins, XCTest calls setUpWithError(), followed by setUp(). Override this method to reset state for each test method. If state preparation might throw errors, override setUpWithError().
https://developer.apple.com/documentation/xctest/xctest/1500341-setup
Example usage:
override func setUp() {
// reset state for each test
}
For comparison, here is the description for the type method setUp from Apple's documentation:
The setUp() class method is called exactly once for a test case, before its first test method is called. Override this method to customize the initial state for all tests in the test case.
https://developer.apple.com/documentation/xctest/xctestcase/1496262-setup
Example usage:
override class func setUp() {
// customize the initial state for all tests
}
I don't know what the purpose of your static variables are, but it sounds like they are responsible for changing behavior in your app. I recommend using mock objects and/or data. I would consider looking into writing "testable code." It will help you keep your code clean and also make it easier for you to write unit tests. It is also object-oriented.

Testing internal classes in swift framework

I did not find a way to unit test an internal swift class that is inside a framework. It only works if I set the class scope to public. Is there a way around it ?
Here is what I have now:
In the framework:
class InternalClass {}
In the tests:
import XCTest
#testable import MyFramework
class InternalClassTests: XCTestCase {
let sut = InternalClass() //ERROR HERE Use of unresolved identifier 'InternalClass'
}
If you want to use your InternalClass as internal class, you must add your InternalClass to your UnitTest target.
You can simple do it by click to the checkbox of the Unit Test target, in the file's Target Membership. (select your file and find it in the Inspectors bar)

Class implemented in app target and test target

I'm using CoreData and have extended the automatic (didn't generate custom class files) model classes by custom variables that return objects of classes coming from an CocoaPods dependency.
import Foundation
import ACocoaPodsFramework
import CoreData
extension MyClass {
var customVar: AClassFromCocoaPods? {
return AClassFromCocoaPods()
}
}
I've added a target for unit tests to the Xcode project and added MyClass and the xcdatamodeld to the test target. A test class looks like the following.
import XCTest
import ACocoaPodsFramework
import CoreData
#testable import MyAppTarget
class MyClassTests: XCTestCase {
}
I have imported ACocoaPodsFramework in both the app and the unit test target as a framework.
When i run the unit tests i receive the following notice
objc[21178]: Class MyClass is implemented in both /.../MyAppTarget.app/MyAppTarget (0x1017703f0) and /... MyAppTarget.app/PlugIns/MyClassTests.xctest/MyClassTests (0x123dc8ae8). One of the two will be used. Which one is undefined.
and exception
Could not cast value of type 'MyAppTarget.MyClass' (0x60c0000ccc60) to 'MyAppTargetTests.MyClass' (0x1258c9a20).
Solved this by removing all app files from the test target and instead importing the needed app files in the test classes using
#testable import MyAppTarget

Swift unit testing with Realm and RAC

I am trying to write some unit tests for my app. I am using Realm and RAC frameworks, but neither of them I can use in my unit tests.
import XCTest
#testable import FlightRecords
class RecordsViewModelTests: XCTestCase {
var viewModelUnderTest: RecordsViewModel!
override func setUp() {
super.setUp()
viewModelUnderTest = RecordsViewModel()
Realm.Configuration.defaultConfiguration.inMemoryIdentifier = self.name
}
}
In the code above, I get an error, but my app is working just normally with Realm (and RAC). The error is:
Use of unresolved identifier 'Realm'
I have tried different combinations for "Target Membership" and none of them worked. At this point, I have all frameworks' Target Membership for both app and tests.
Any advice?
You need to import RealmSwift in your test cases, also you should add the parent path to RealmSwift.framework to your unit test’s "Framework Search Paths".
See also https://realm.io/docs/swift/latest/#debugging

Eclipse: how to update a JUnit test file with newly added method in the source file?

Using Eclipse (Helios), I could create a JUnit test file ClassATest.java of the source file ClassA.java by using New -> JUnit Test Case -> Class under test..., then choose all the methods of ClassA to be tested.
If later we add some more methods to ClassA, how do we easily reflect this addition in ClassATest ? (No copy/paste plz).
One solution is to use MoreUnit
With MoreUnit installed to Eclipse, one can right click onto the newly added method (and not yet unit tested), and choose "Generate Test"
Of course, if one always follows the writing-test-before-writing-method style, then this solution is not needed. However in reality sometimes you don't have a clear idea of what you would want to do, in that case you would have to code up some method, play with it, then rethink and code again until you are satisfied with the code and want to make it stable by adding unit test.
You should look into creating a JUnit test suite which will execute all tests within the classes you specify. Thus, adding new test cases is as simple as creating a new class and adding it to the #Suite.SuiteClasses list (as seen below).
Here's an example.
Example JUnit Test Suite Class:
#RunWith(Suite.class)
#Suite.SuiteClasses({
TestClassFoo.class
})
public class ExampleTestSuite {}
Example Test Case class:
public class TestClassFoo {
#Test
public void testFirstTestCase() {
// code up test case
}
}