How to use UIAutomation on a Today extension widget? - ios

I am trying to use UIAutomation for testing an iOS 8 Today extension widget. I can change the target to the extension, launch it, but then unable to do anything after that.
Has anyone had any success in using UIAutomation with the extensions?

I hope I have the right end of the stick on this one.
I think you want to create a set of UI Tests which run like you can do with a normal application.
I found that I was not able to create a specific UI Tests target to then set the target application as WidgetExtension, as you would normally.
However I was able to set the WidgetExtension target to build and run onto a device (>= iOS 14) then within my UI Tests, I was able to record some steps which would allow me to write a clearer UI Test (place the cursor inside a test function to use record, you might already know this).
The tricky bit would be keeping the WidgetExtension target up-to-date onto the testing simulator to run your automated tests.

Related

Record button disabled in Xcode UI Test Target

I know similar questions have been posted, but from my investigating, there has not been a solution posted, at least not one that works. I have successfully run UI tests only from sample projects in both Swift and Obj-C.
I am trying (unsuccessfully) to integrate UI tests into an existing Xcode Obj-C project, which seems to be another issue altogether. Here are the steps I have taken:
Created a new UI Test target within my project
Ensured that 'Enable Testability' has been set to YES for the target I am testing
Cleaned, cleaned build folder, rebuilt the app, restarted Xcode and everything else I could think of.
When I do this, the test target is available but the record button is greyed out (disabled) and there are no play buttons in the gutter to execute the tests. There is nothing visual about the test class that would indicate that it is a test class. When I place my cursor in the test method, the record button remains disabled.
Is there anything I've left out? Anything else to check that might be preventing UI tests?
Record button only gets enabled within a function body.
The function name must start with test. Like testExample().
After changing the name of the function wait for a few seconds for the run icon to appear in the gutter.
Now the record button should appear.
Make sure you are in the correct XCTestCase subclass file.
After researching for a time, I found that I was all the time in a extension file (I'm been ordering the flows in extension files). So when I opened the main XCTestCase subclass file (like "YourAppUItests") the record test button has been enabled.
Click on 6th button from top of the left pane - Show the test navigator
Right click on the UI tests, then click on "Enable ... "
Then you can record.
Make sure you can build for the test target successfully.
Go to Product > Test, and make sure the UI Testing test case is run (it is fine if the test case is empty). You should also see the test cases under Test Navigator, or in the app target scheme.
I followed all the tips listed here, and the only thing that fixed it was restarting Xcode.
Make sure you have at least one test function in your ui test class. For example- func testExample(){}. Then you'll be able to record in that function as you can only run functions as tests if they have test as prefix.
I realized you had to have your cursor inside the test function you want to record for. I simply clicked inside the test function and the record button got enabled.
Also, make sure you select the UI test scheme, which was the problem in my case:
If your project has a test plan (.xctestplan) then make sure that the new test is enabled. Till then the record button will be disabled. This often happens when you add a new UI Test Case Class. Or when you add new test to existing class which has some of the tests disabled.
create function in yourfileUITests.swift
running program by TEST
your function can record UI Testing, button already enable

How do I take screenshots of my UI with Xcode 7 during UI Testing?

So I downloaded the beta of XCode 7 and I've created some UI tests, but I can't find the functionality of how to take screenshots of my app/UI during the test.
Can someone please help?
UI Testing in Xcode automatically takes screenshots of your app after every step.
Simply go to one of the tests that has already ran (Report Navigator > choose a Test), then start expanding your tests. When you hover your mouse over the steps, you will see eye icons near each step that has a screenshot.
Here's an example... in this case, notice the eye icon at the end of the gray row. If I were to tap on it, I would see a screenshot of the app right when the button in my app was tapped (since the step is Tap the "Button" Button).
If you want to generate screenshots, you can also use snapshot, which describes how to trigger screenshots in UI tests: https://github.com/fastlane/fastlane/tree/master/snapshot#how-does-it-work
It basically rotates the device to .Unknown (Source), which triggers a snapshot without actually modifying your app's state.
Comparing the output with the generated plist file enables you to even properly name the screenshot
Facebook's ios-snapshot-test-case and KIF both run as Unit Tests, and therefore are in the same process as the app. As such, they can directly access views and use something like renderView: or snapshotViewAfterScreenUpdates. Xcode UI Testing runs in a separate process, and therefore cannot directly access the views.
UI Automation, Apple's now-deprecated Javascript UI testing library, had a function calledcaptureScreenWithName.
Unfortunately, the new Xcode UI Testing lacks any similar function in its testing library, which to me seems like a glaring omission and I encourage you to submit a Radar for it, as taking screenshots is fundamental to perceptual difference tests (which it sounds like you're trying to do). I hope (and expect) that able will address this deficiency in later Xcode updates.
In the meantime, there are more creative approaches to taking screenshots. See this stack overflow response for a workaround involving taking the screenshot in the app itself and then sending it to the test process.
I' ve created a tool that saves the tests last n screenshots and generates the JUnit tests results report, parsing TestSummaries plist file from test logs. https://github.com/nacuteodor/ProcessTestSummaries
Maybe, that helps you.
Facebook's FBSnapshotTestCase can be alternative solution:
https://github.com/facebook/ios-snapshot-test-case

Connecting external framework to UI unit testing target, iOS

So, i have already existing project at my hands and i’m trying to create some UI tests by using this new fancy UI Testing Bundle provided by apple. The problem is that test target doesn't have access to any external framework (and i need to do some setup with one of them). Adding framework in build phases and coping framework search path from main target doesn't do anything.
After day of browsing i found out only one thing, that ”makes things kinda different”. By setting up Bundle Loader and Test Host to $(BUILT_PRODUCTS_DIR)/App.app/App , i still couldn't import external frameworks to test.m, but i could import classes that do that for them self. And it all would be fine and dandy unless it didn't break some stuff. By setting Bundle and Host now my UI test is unable to execute launch method:
[[[XCUIApplication alloc] init] launch];
It crashes with error: Assertion Failure: UI Testing Failure - App state is still not terminated.
In the end i could remove launch method from setup and trigger every single test manually, so it restarts application every time before executing, but this solution seems so wrong (especially for some bigger projects). Does anyone know proper way to handle this problem?
What I've done for this is add an environment variable to XCUIApplication to specify UI tests are being run. I then have a pre-processor check for #DEBUG in a main part of the application, and then check if the test environment variable has been set; if it has, do the necessary steps for the UI tests.
Essentially, this will allow you to configure your app to how you need it for the UI tests to run. It also means the pre-processor check will strip out that setup code entirely for the release build.

Is there any way to test the code coverage of UIAutomation tests?

I am using UIAutomation to test an app, and I would like to find out my code coverage. But since javascript has no preprocessor, that means that gcov and similar are not an option. Has anyone come up with a solution for this?
For Xcode version 4.5 and newer:
Set the “Generate Test Coverage Files” build setting to Yes.
Set the “Instrument Program Flow” build setting to Yes.
This will generate code coverage files every time you run your application in the simulator and exit the application. A detailed explanation of these two steps can be found at the beginning of http://qualitycoding.org/xcode-code-coverage/.
For any unit tests, code coverage files will be generated every time you hit the test button and the tests complete. For UIAutomation, it is a little bit more tricky. You have to ensure the application exits at the conclusion of your tests. The easiest way I found to do this is to turn off multitasking. Add UIApplicationExitsOnSuspend in your MyAppName-Info.plist file and set this option to 'YES'. Run your UI automation test and at the end of it you can exit the app either by manually pressing the home button in the simulator or using the UIATarget.localTarget().deactivateAppForDuration() method.
Note: if your app has any UI Automation tests that rely on the deactivateAppForDuration() method, the tests will terminate upon running the command.
Code Coverage is only used for Unit Testing, there is no Code Coverage for UIAutomation because there is no way to tell how many elements on screen has been "touched" by UIAutoamtion

Testing a location based iOS application using Frank

I am investigating the available testing frameworks for iOS,
I want to write tests for an iOS app that are location dependent, like if you are at place A (I mean geo-location) this testStep should fail and that one should succeed and in location B the situation is the other way around,
Is there a way to simulate being at a location when writing Frank tests, in the simulator, and not by manually choosing a gpx file for each test separately,
EDIT: to make it clear, I want to do it in my tests, so it should be done in my code or with calling an external script or in some automatic way, I want to run tests that should happen in different locations.
as of Frank 1.1.1 you can now ask Frank to simulate a location using the set_location method. For an example of how this works take a look at this step definition from the example app that comes with Frank.

Resources