How To Run XCTest in Xcode 5.1 - ios

I'm trying the XCTest framework
#implementation UnitTestPOCTests
- (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)testAditionClass
{
Addition *addObj = [[Addition alloc]init];
XCTAssertNotNil(addObj,#"AddtionClassExists");
}
I wrote the testAditionClass test method inside my test class, but when i run the test methods its showing Testing.... in the status bar
its not even getting terminated.
If any one know the the solution please help me.
Thanks in advance

I resolved this problem by opening the simulator you will have the following options in menu
if you tap on reset content and setting.
Then try running unit test it works for me.

Related

Newly created test case class is not shown under Test Navigator in Xcode

My XCode version is 7.3.1 .
My project already has test project, and there are already some test case classes. I can see them when select the "Test Navigator" tab which is one of this on left top of XCode.
Now, I want to create a new test case, so I selected the new Unit Test Case Class:
And I add very simple code into it:
#import <XCTest/XCTest.h>
#interface MyTest : XCTestCase
#end
#implementation MyTest
- (void)setUp {
[super setUp];
}
- (void)tearDown {
[super tearDown];
}
- (void)testExample {
NSString* expected = #"my-test-string";
XCTAssertEqual(expected, #"my-test-string");
}
#end
I need to run it, so I go to "Test Navigator" again, but I can't see this test case class I just created. Why?
Restarting Xcode is the only thing that worked for me in Xcode 9.0 beta 6.
It appears that Xcode adds the individual testmethods/classes only after the whole unit test target has been run at least once.
So select your test target, run all tests using Command u. After that you should see all tests in the test navigator and you can run them individually.
Sometimes the unit test appears in Test Navigator after you Save (CTRL+S) the unit test's file in XCode.
Remember to keep the test prefix on the test methods, otherwise they are not recognized by the test framework, e.g.:
func test_When_empty_Then_returnsNil() {
not
func when_empty_Then_returnsNil() {

iOS testing with XCTest and separate file

Currently, I write my testing in 1 file (default). Is it possible to have multiple files and test?
- (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");
}
You can have many files and many tests per file. The first one is just the one made by Xcode automatically, but all that makes it special is that it:
Implements a subclass of XCTestCase
Is a member of the testing target (not your app target)
Making another file with the same characteristics is simple.
In Xcode, File -> New -> iOS -> Source -> UI Test Case Class
The convention is to group related tests into a source file, and then name that source file ___Tests.swift (or .m)
For example, SharingTests.swift might contain the methods testSharingToFacebook() and testSharingToTwitter().

How to detect if iOS app is running in UI Testing mode

I would like my app to run special code (e.g. resetting its state) when running in UI Testing mode. I looked at environment variables that are set when the app is running from UI Testing and there aren't any obvious parameters to differentiate between the app running normally vs in UI Testing. Is there a way to find out?
Two workarounds that I'm not satisfied with are:
Set XCUIApplication.launchEnvironment with some variable that I later check in the app. This isn't good because you have to set it in the setUp method of each test file. I tried setting the environment variable from the scheme settings but that doesn't propagate to the app itself when running UI Testing tests.
Check for the lack of existence of the environment variable __XPC_DYLD_LIBRARY_PATH. This seems very hacky and might only be working now because of a coincidence in how we have our target build settings set up.
I've been researching this myself and came across this question. I ended up going with #LironYahdav's first workaround:
In your UI test:
- (void)setUp
{
[super setUp];
XCUIApplication *app = [[XCUIApplication alloc] init];
app.launchEnvironment = #{#"isUITest": #YES};
[app launch];
}
In your app:
NSDictionary *environment = [[NSProcessInfo processInfo] environment];
if (environment[#"isUITest"]) {
// Running in a UI test
}
#JoeMasilotti's solutions are useful for unit tests, because they share the same runtime as the app being tested, but are not relevant for UI tests.
I didn't succeed with setting a launch environment, but got it to work with launch arguments.
In your tests setUp() function add:
let app = XCUIApplication()
app.launchArguments = ["testMode"]
app.launch()
In your production code add a check like:
let testMode = NSProcessInfo.processInfo().arguments.contains("testMode")
if testMode {
// Do stuff
}
Verified using Xcode 7.1.1.
You can use Preprocessor Macros for this. I found that you have couple of choices:
New Target
Make a copy of the App's target and use this as the Target to be Tested. Any preproocessor macro in this target copy is accessible in code.
One drawback is you will have to add new classes / resources to the copy target as well and sometimes it very easy to forget.
New Build Configuration
Make a duplicate of the Debug build configuration , set any preprocessor macro to this configuration and use it for your test (See screenshots below).
A minor gotcha: whenever you want to record a UI Testing session you need to change the Run to use the new testing configuration.
Add a duplicate configuration:
Use it for your Test:
Swift 3 based on previous answers.
class YourApplicationUITests: XCTestCase {
override func setUp() {
super.setUp()
// Put setup code here. This method is called before the invocation of each test method in the class.
// In UI tests it is usually best to stop immediately when a failure occurs.
continueAfterFailure = false
// UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
let app = XCUIApplication()
app.launchArguments = ["testMode"]
app.launch()
// In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
}
override func tearDown() {
// Put teardown code here. This method is called after the invocation of each test method in the class.
super.tearDown()
}
func testExample() {
// Use recording to get started writing UI tests.
// Use XCTAssert and related functions to verify your tests produce the correct results.
}
}
extension UIApplication {
public static var isRunningTest: Bool {
return ProcessInfo().arguments.contains("testMode")
}
}
Then just call UIApplication.isRunningTest in your code.
I've just added this extension
#available(iOS 9, *)
extension XCUIApplication {
func test(){
launchEnvironment = ["TEST":"true"]
launch()
}
}
So I can just use test() instead of launch()
In Swift 3 you can check for the XCInjectBundleInto key, or something that starts with XC.
let isInTestMode = ProcessInfo.processInfo.environment["XCInjectBundleInto"] != nil
This works in OS X as well.
My solution is almost identical to that of Ciryon above, except that for my macOS Document-based app I had to prepend a hyphen to the argument name:
let app = XCUIApplication()
app.launchArguments.append("-Testing")
app.launch()
...otherwise, "Testing" ends up interpreted as the name of the document to open when launching the app, so I was getting an error alert:

Aviary SDK crash on initializing on iOS

I integrate Aviary SDK on my app to enhance my app image editor feature. I read its documents, run its sample code and it works fine. But when run on my app, I face an issue. It crashed EXC_BAD_ACCESS after run over a method
[AFOpenGLManager beginOpenGLLoad];
I followed the setup guide on Aviary document
https://developers.aviary.com/docs/ios/setup-guide#project-setup
At first, I just create a Singleton manager to manage. I call [AFOpenGLManager beginOpenGLLoad]; on init function
- (id)init {
if (self = [super init]) {
[AFOpenGLManager beginOpenGLLoad];
}
return self;
}
- (void) launchPhotoEditorWithImage:(UIImage *)editingResImage
highResolutionImage:(UIImage *)highResImage
fromController:(UIViewController *)controller
{
// Customize the editor's apperance. The customization options really only need to be set
once in this case since they are never changing, so we used dispatch once here.
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[self setPhotoEditorCustomizationOptions];
});
// Initialize the photo editor and set its delegate
AFPhotoEditorController * photoEditor = [[[AFPhotoEditorController alloc]
initWithImage:editingResImage] autorelease];
[photoEditor setDelegate:self];
// If a high res image is passed, create the high res context with the image and the
photo editor.
if (highResImage) {
[self setupHighResContextForPhotoEditor:photoEditor withImage:highResImage];
}
// Present the photo editor.
[controller presentViewController:photoEditor animated:YES completion:nil];
}
After run over the init function, it crashed on
Do I miss somethings, the sample code run well.
Edit 1:
compileShader is called from createProgram but I can read this method
Edit 2:
I realize somethings. My app project has a lib named libmediastreamer_voip.a . I think there is misunderstanding. I mean maybe Aviary lib and libmediastreamer_voip.a lib also have the function named compileShader. So when on Aviary lib calls compileShader it runs on compileShader on Aviary lib but run into compileShader on libmediastreamer_voip.a.
I wonder I could be like that? I create a new project and integrate Avairy SDK, it works well, just integrate to my app it crashes
I am a member of the iOS team at Aviary. This is caused by a conflict between our compileShader function and yours. Our function was not properly namespaced and resulted in the conflict. We will be addressing this in the next release of the SDK.
Michael
What I think about it. Check your shader value. It should have correct shader path from your resources or somewhere else with appropriate type (GL_VERTEX_SHADER or GL_FRAGMENT_SHADER).
Seems to me you've it's nil

iOS Test Failure - "No Implementation for…"

After completing my app I run a test from Xcode, Product -> Test, it says 'Build Succeeded' and the app pops up for a split second, but then it prompt me with this message:
I have searched a lot but couldn't find any solution that works in this case. I want to mention that I have also tried changing the name of the application from, CSQTCConference, to CSQTC Conference, not sure how relevant this is.
I am planning to release my application to app store today, but this issue is holding it back. It will be helpful if you can suggest any pointers to resolve this issue.
I just comment the following line:
//XCTFail(#"No implementation for \"%s\"", __PRETTY_FUNCTION__);
in:
#import <XCTest/XCTest.h>
#interface KinderAppTests : XCTestCase
#end
#implementation KinderAppTests
- (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
{
//XCTFail(#"No implementation for \"%s\"", __PRETTY_FUNCTION__);
}
#end
This solution worked for me, hope it helps :)
I'm not familiar with XCTest but I assume XCTFail will always fail, so no big surprise here.
You are running boilerplate example code, which created a test that always fails. If you haven't written your own tests what's the point of running them in the first place?
The real question is: Why is this happening?
Answer: You did a Command U, or selected test. This ran the default test, which always fails.
Correction: Comment out the fail line, and run it again.

Resources