I'm working on adding UITest to my iOS app. I've gone through the steps to create the new UI Test Target, but when I try to even run the sample test, it seems to be pointing to the same target as my Unit Test (which inevitably fails)
Where do I go in Xcode to configure the target for UI tests?
Thanks!
Related
I am currently building out a test suite in an Xcode workspace that contains 3 existing projects. 2 App projects and a common framework project. Both apps are very similar in regards to UI with some minor differences.
I am trying to find a way to share the XCUITest framework I made for App A with App B.
Currently, App A has a test target set inside of its AppA.xcodeproj. All of App A's tests are doing great and easy to maintain. I need to extend this to App B and refactor App A's framework to only the App A exclusive bits so App A and App B can share the common XCUITest framework code base from a central base.
I have tried to create a new project, move over the UI test code and point the new UI Test target at App A's executable, but I could not figure out how to get the option to show.
I set the App A app as a Target Dependency in the New Project's test target > Build Phases tab, but no luck. I was able to set App A's target in the new test target's scheme but still landed on an error.
Assertion Failure: CommonBasePage.swift:21: failed: caught "NSInternalInconsistencyException",
"No target application path specified via test configuration: <XCTestConfiguration: 0x60400014e910>
testBundleURL:file:///Users/user.name/Library/Developer/Xcode/DerivedData/.../Debug-iphonesimulator/NewTestTarget-Runner.app/PlugIns/NewTestTarget.xctest/
testBundleRelativePath:(null)
productModuleName:NewTestTarget
testsToSkip:(null)
testsToRun:NewBasePage/testExample
reportResultsToIDE:YES
sessionIdentifier:<>
pathToXcodeReportingSocket:(null)
disablePerformanceMetrics:no
treatMissingBaselinesAsFailures:no
baselineFileURL:(null)
baselineFileRelativePath:(null)
targetApplicationPath:(null)
targetApplicationBundleID:(null)
testApplicationDependencies:
{...
I'm assuming targetApplicationPath:(null), targetApplicationBundleID:(null) should have legit target values but I'm unsure where else to look in order to set them.
I gave up on that and tried to create a new project & target as a Cocoa Touch Framework to shift the common code to a central point but was not able to import XCTest, which my framework depends on for XCUIApplication and XCUIElement fields.
import XCTest //Causes "Cannot load underlying module for 'XCTest'"I tried adding XCTest.framework to the targets "Link Binary with Libraries" section under build phases but no luck.
Is there a way to work with the XCTest framework outside of a test target?
OR
Is there a way to point one project's test target at another project's app target?
You can link XCTest and any other framework to anything. Make sure you have $(PLATFORM_DIR)/Developer/Library/Frameworks in both LD_RUNPATH_SEARCH_PATHS and FRAMEWORK_SEARCH_PATHS.
Making framework for shared code is a good idea.
We have the following project structure:
Workspace:
- app project
- cocoapods project
App scheme:
- app target (run)
- ui test target (test)
- unit test target (test)
After upgrading to Xcode 10, Xcode insists on building the entire project, including pods and ui tests, every time I run a single unit test, which is a quite heavy and slow process.
If i create a seperate scheme which only include the unit and/or ui tests, it only rebuilds the tests when I run them. Just as I want.
However, as they are no longer member of the main app scheme, I can no longer press Test on the main scheme, as it no longer contains test targets.
My question is then: Is it normal or recommended to have seperate schemes for tests, or can I prevent the entire project from being rebuild in another way, when running a single unit test?
(note: I have set the Host Application setting to None on the unit tests, so I don't get why it always builds the entire project anyway?)
Why not both? In your "Test All the Things" scheme, add each test target. This scheme should be shared.
But when I'm working in one target, I make a scheme for it alone. (More accurately, AppCode creates one for me.) Such schemes are not shared.
I'm developing cross platform app for Android, Windows Desktop 8.1, WinPhone 8.1, iOS on Xamarin and now added Test projects. I went through multiple resources for UITests but had following queries. It could be helpful if anyone can correct me.
Projects of type Android test, Windows Phone test, iOS test exists. When these are run, these executes as an app in device/emulator. So, how would these test original app running on same device?
If I have two different android project, how can I specify in above test projects which one to test?
I also added UITest project, which is class library project. In this I can mention apk file using following code:
[SetUp]
public void BeforeEachTest()
{
app = ConfigureApp.Android.ApkFile(#"Path\to\apk\com.namespace.apk")
.DeviceSerial("emulator-1234")
.StartApp();
}
How to reference a project to test rather then .apk file, so I could modify project every time I run tests?
How can I combine UITest project and native test projects? Like common portable library is referenced by native projects.
Thanks in advance
Regarding point 4.
At present, running console UnitTests against Xamarin.Forms, i.e testing the ViewModel, Commands, and Navigation in isolation of the UI takes a fair bit of setup. Testing the ViewModels in total isolation of the Xamarin.Forms framework disallows testing across multiple ViewModels.
For instance, testing a login viewmodel in complete isolation where:
user enters username/password
click login button
redirected to the authenticated screen with their data populated
will not work, as that requires a hook on the viewmodel navigation, so the test can authenticate on the Login ViewModel, then navigate and initialise the Authenticated ViewModel.
So I put out a nuget library that allows to simply achieve this, and also provide Bdd using specflow. The test run as nunit test on vs test shell, or any nunit console runners (such as in Build Servers such as Team City).
Example:
public class GeneralSteps : TestStepBase
{
public GeneralSteps(ScenarioContext scenarioContext)
: base(scenarioContext)
{
// you need to instantiate your steps by passing the scenarioContext to the base
}
[Given(#"I am on the main view")]
public void GivenIAmOnTheMainView()
{
Resolver.Instance.Resolve<INavigationService>().PushAsync<MainViewMode>();
Resolver.Instance.Resolve<INavigationService>().CurrentViewModelType.ShouldEqualType<MainViewModel>();
}
[When(#"I click on the button")]
public void WhenIClickOnTheButton()
{
GetCurrentViewModel<MainViewModel>().GetTextCommand.Execute(null);
}
[Then(#"I can see a Label with text ""(.*)""")]
public void ThenICanSeeALabelWithText(string text)
{
GetCurrentViewModel<MainViewModel>().Text.ShouldEqual(text);
}
}
Step by step instructions here
Nuget package here
Not sure I understand this question.
UITest will deploy and run the app in the device/emulator and will then run the tests against that app. For iOS apps being tested it will start the emulator for you. For Android apps being tested you will have to start the emulator yourself. If they are different Android apps then presumably the UITests would be different for each Android app so keeping the UITests as separate project seems reasonable, especially if you are uploading the tests to Xamarin Test Cloud.
Also note that UITest does not support Windows Phone projects currently, so it can only be used to test your Android and iOS project.
With two different Android projects you would either create a UITest project for each Android project or you would need to specify the path to the .apk file in the test, using ConfigureApp.Android.ApkFile () as you have already done in the code example.
If you are using Xamarin Studio you can run the UITests directly in the IDE without having to specify the full path to the .apk file or the iOS .app.
What you would need to do is have the UITest project reference the Android project. However it needs a special type of reference so you will need to use Xamarin Studio to do this. You add this special type of reference from the Unit Tests window, by finding the Test Apps item, selecting Add App Project and then selecting the Android and/or iOS project.
More information is available in the Adding UITest to a solution on Xamarin's developer guide.
Note that you can have a single UITest project test both the iOS and Android apps. Assuming that they are both the same application. However you may need to create Android and iOS specific UI test queries to find UI elements on the screen.
First you should ask yourself if you really need to combine UITests with native test projects. For example the UITests may take a long time to run, so if you have some fast unit tests you may not want to run them all together.
Combining them is possible if the native test projects are essentially NUnit projects. A UITest project is basically a NUnit project. It has a reference to NUnit and is a class library. If your native tests can be run from a NUnit project then you could combine them. However you would not be able to run the native tests in Xamarin's Test Cloud.
If the native test projects do not use NUnit then you cannot combine them with the UITest project.
In an existing ios app and project, how do I enable an existing test target and classes to support UI testing and the record UI test button?
I can add a new test target and I'll see the record button if I do that, but what if I wanted to add some UI testing functions to an existing test class and target?
UI Testing is in a separate target from normal unit test cases, so you can't just add UI testing to you existing test cases.
You should use new UI test target to add/execute your ui tests for clean build and maintenance purpose.However, assuming you are trying to call XCUI* APIs in your unit test classes and enable UI recording with unit test target, I see couple of issues cropping up there,
If you are using swift2 for unit testing and including your main app modules using #testable import {module}, when you call XCUI* menthods from this testcase, swift will throw an error
Module {module} was not compiled for testing
Since UI test run as separate process, it can't load you app code dependencies.
Since XCUI* api depends on Obj-C libraries, invoking UI test methods would expect you to include Objective-C Bridging Header file in your unit test target. It would not error out but it pollutes your target.
I also verified that you need to add your test case file to UI test target in order to enable UI test recording button.
There are other benefits of running UI tests as a separate target, e.g flexibility of specifying the target to only run unit test or UI test from the command line tools and ease of maintaining clean state for UI tests execution.
In Xcode 4.x any unit tests (logic tests) could run as part of building your main target.
Is a similar setup possible for Xcode 5?
Update
The issue boils down to Xcode launching the simulator as part of running logic tests. That wasn't the case with Xcode 4.x
Have created a radar to track this http://openradar.appspot.com/15859153
To build and run unit tests after building the other targets in the active scheme, use command-U.