Parallel testing with UI Testing Xcode - xcode7

Can I open multiple simulator on the same mac in order to do parallel testing using UI Testing from Xcode?

Update May 2018:
Bluepill allows tests to be split across multiple simulators and supports XCUITests:
we recently added support for Xcode UI Testing bundles. Thanks to the
inspiration from FBSimulatorControl. Bluepill now supports Xcode unit
test bundle and UI test bundles.
Original answer:
There doesn't seem to be a viable solution at the moment. However promising tools are coming into place. There's a framework called FBSimulatorControl and it's cli tool called fbsimctl which allows you to boot multiple simulators at once, and install & run apps.
With fbsimctl you could build you target application & install it on each simulator. The part I'm stuck on is how to build & install the companion XCTestUI runner app.
xcodebuild doesn't appear to allow building the XCTestUI runner app without invoking the test action (causing alerts that multiple simulators are open). If xcodebuild could allow the building the .app/.ipa for the runner app only, then it looks like fbsimctl could handle the rest.
There's also an open issue over at facebook/xctool trying to work through this problem.

Parallel UI testing is possible if you use multiple users on your mac and some kind of a continuous integration system. If done correctly you can run your UI test suite on a variety of device simulators at the same time. In other words you'd be able to run all your UI tests against many devices in the time it takes to run those tests on one device - which is what I think we're trying to accomplish here. The following are instructions on how I was able to get parallel UI tests up and running with gitlab-ci-multi-runner. These instructions assume you have never used any of the tools but are not instructions on how to write UI tests:
Install Xcode through the mac app store.
Open the mac app store.
Type "Xcode" into the search field
Navigate to the Xcode install page and click "Install"
Note: I used Xcode 8.2 at time of writing this.
Install the Xcode command line tools.
Open terminal and enter the following command xcode-select --install
Note: You will be needing Xcodebuild, so this step is critical.
Create a few new "test" users on your mac.
Open system preferences and click on "Users & Groups".
Click the lock icon on the bottom left of the window to make changes.
Enter a "User Name" and "Password" and then click "Unlock".
Click the "+" add button located at the bottom of the list of users on your mac.
Select "Administrator" in the "New Account" dropdown menu.
Give your user a name in the "Full Name" text field (i.e. Test User One)
Click on the "Account Name" text field and allow it to auto fill.
Enter a password of your choosing into the "Password" text field.
Re-enter the password into the "Verify" text field.
Optionally enter a password hint into the "Password Hint" text field.
Click "Create User".
Repeat step two several times. Note: the number of users you create will determine the number of devices will run through your UI test suite at a time. In this solution we will discuss just running tests against several different devices at once on a single mac.
Create an account on gitlab.com.
Create a new project on gitlab.
Here is a tutorial on how to do that.
Follow the "Command line instructions" on your new project detail page to move your Xcode project into a gitlab repository.
Create SSH keys for each test user:
Sign into each of the "test" user accounts you just created. Note: It is important each user be signed in so the gitlab-ci system can run tests on that user. If not the tests will fail.
Open terminal again and type ssh-keygen -t rsa
Follow this tutorial complete this process.
Navigate to your gitlab "Profile Settings" page and then to the "SSH Keys" tab.
Use pbcopy < ~/.ssh/id_rsa.pub in terminal to get your generated SSH key in each 'test' user account and then use cmd+v to paste each the SSH key into the "Key" text field on the "SSH Keys" tab in gitlab.
Note: It is critical for each 'test' user to have access to your project code in gitlab so don't skip this step for any of your test users.
Note: I personally like to test each user has access to the repo by doing a git clone while logged into each of the "test" users.
Create test "runners" on/for each of your "test" users on your mac.
Open your gitlab project page on gitlab.com.
Click on the project settings icon.
Click on the "Runners" link.
The important information on this page is the URL and registration token highlighted in red under the "How to setup a specific Runner for a new project" section of the page.
Open terminal and type sudo curl --output /usr/local/bin/gitlab-ci-multi-runner https://gitlab-ci-multi-runner-downloads.s3.amazonaws.com/latest/binaries/gitlab-ci-multi-runner-darwin-amd64 then hit return.
Type sudo chmod +x /usr/local/bin/gitlab-ci-multi-runner then hit return.
Type gitlab-ci-multi-runner install then hit return.
Type gitlab-ci-multi-runner start then return.
Type gitlab-ci-multi-runner status then hit return to ensure the service is running.
Type gitlab-ci-multi-runner register and hit return.
Copy and paste the URL from the gitlab page described above into terminal and hit return.
Copy and paste the token from the gitlab page described above into terminal and hit return.
Enter a description for this "test" user runner and hit return.
Enter a tag unique to this particular "test" user and hit return.
Type Shell and hit return.
Verify the runner has been added and has a green dot net to it on your gitlab runners page.
Note: It is critical for this solution to set up individual runners for each of your "test" users you set up on your mac to run tests in parallel on different devices. Equally critical is that you give different tags to each of your "test" user runners so gitlab can tell each "test" user to run your UI tests.
Open terminal and type nano /Users/{test user name}/.gitlab-runner/config.toml and hit enter.
On the first line replace the number "concurrent = 1" with how ever many "test" users you created. Then hit shift+x, y, then return to save changes.
Note: Make sure it's done on each user to ensure parallelism.
Create a UI test scheme for your Xcode project.
Click the scheme dropdown menu near where you would select which device to run the project on.
Select "New Scheme".
In the "Target" dropdown menu select option that contains "UITests" in the title. Then click "OK"
Click the same scheme dropdown menu as described above and then select "Manage Schemes".
Make sure the checkbox is checked to make the "UITests" scheme "Shared".
Click close.
In terminal type git add . and hit return to ensure the schemes file is included.
Type git commit -am "Added ui test scheme" and hit return.
Type git push and hit return.
Create a gitlab-ci.yml file for your project.
Create a gitlab-ci.yml file in the root folder of your project in the text editor of your choice.
Here is an example yml file for an example project I created:
before_script:
- carthage update
stages:
- test
iphone_4s_tests:
stage: test
script:
- xcodebuild test -configuration Debug -project parallel.xcodeproj -scheme parallelUITests -destination 'platform=iOS Simulator,name=iPhone 4s' | xcpretty --simple
tags:
- iphone_4s
iphone_5s_tests:
stage: test
script:
- xcodebuild test -configuration Debug -project parallel.xcodeproj -scheme parallelUITests -destination 'platform=iOS Simulator,name=iPhone 5s' | xcpretty --simple
tags:
- iphone_5s
iphone_6_tests:
stage: test
script:
- xcodebuild test -configuration Debug -project parallel.xcodeproj -scheme parallelUITests -destination 'platform=iOS Simulator,name=iPhone 6' | xcpretty --simple
tags:
- iphone_6
IMPORTANT NOTE: Each tag should correspond with a tag on each one of the runners installed on the "test" user. The key here is that your test suite will be run on individual device
While in your project directory in terminal type git add .gitlab-ci.yml and hit enter.
Type git commit -am "Added the .gitlab-ci.yml file to the project." and then return.
Type git push and then return.
BOOM! If you've done everything correctly then your wildest dreams of testing your UI against many iOS devices in parallel has finally been realized. You'll notice that when you navigate to your gitlab project page and then the "Piplines" tab your UI tests are now running across in parallel. IMO this is the cheapest and most efficient way to get all your UI testing done. In the time it takes your test suite to complete one round on one device you can - in theory - complete the UI testing for all the devices you wish to test against. This solution is much cheaper than trying to buy several devices and having them all test at the same time. Generally speaking a single mac, depending on the specs, can run 10 - 15 devices at a time if there is nothing else taxing the CPU.

As of Xcode 9, you can now boot multiple simulators together and also can run parallel tests on multiple devices.
See the What's New in Xcode 9 Apple Documentation page for more information.

Have a look at plu/pxctest tool to execute tests in parallel ios simulators. It is much easier to integrate with project when compared to blue pill.
https://github.com/plu/pxctest

Parallel testing in now possible with the Simulator as announced in the What's New in Testing WWDC 2018 session:
Hear about exciting improvements to code coverage, including how you can build your own automation on top of Xcode's coverage reports. Learn how to dramatically speed up the execution of your tests by leveraging distributed parallel testing, new in Xcode 10.

For running UITests in parallel using multiple simulators check out this amazing open source library by LinkedIn >
https://github.com/linkedin/bluepill

Related

What server URL should be used for the `oc login` command when using OpenShift's PaaS?

What do I provide for the server URL in the oc login tool, when using the OpenShift PaaS?
I'm trying to migrate my OpenShift Online v2 app to v3, following the instructions for PHP apps linked to from OpenShift's Migration Center. That page says to run something following the pattern oc new-app https://github.com/<github-id>/<repo-name>.git --name=<app-name> -e <ENV_VAR_NAME>=<env_var_value>. After tracking down a download for oc (which wasn't easy), I tried running that command with my repo URL*; this results in:
$ oc new-app https://USERNAME#bitbucket.org/USERNAME/PROJECTNAME.git --name=PROJECTNAME
error: Missing or incomplete configuration info. Please login or point to an existing, complete config file:
1. Via the command-line flag --config
2. Via the KUBECONFIG environment variable
3. In your home directory as ~/.kube/config
To view or setup config directly use the 'config' command.
Not knowing what subcommand of oc config to use, I searched and found Get Started with the CLI, which says to use oc login to start the configuration process. But when I run that, I get:
Server [https://localhost:8443]:
What do I provide for the URL here, when using the OpenShift PaaS (i.e. not a local installation)? I've tried things like https://openshift.com/ and the URL of my web app, but both of them result in
error: The server was unable to respond - verify you have provided the correct host and port and that the server is currently running.
* I decided to use Bitbucket instead of GitHub; I'm not sure if this is unsupported, or (if it's supported) whether I should be providing USERNAME#bitbucket.org.
It is right over there in the web console.
Click on (?) help icon right beside your user name on top right corner. Select 'Command Line Tool' from the drop down menu.
Alternatively, it is there in the URL :
http://<openshift url>/console/command-line
e.g. it is mentioned on the below URL for me:
https://console.starter-ca-central-1.openshift.com/console/command-line
Hope it helps.
In the RedHat OpenShift Online web console, click on the (?) help icon right beside your user name in the top right corner. Select 'Command Line Tools' from the drop down menu.
A pop-up window appears with a section "oc - OpenShift Command Line Interface (CLI)", and there's a link for Copy Login Command. Click that and it takes you to a page like
https://oauth-openshift.apps.ca-central-1.starter.openshift-online.com/oauth/token/display?code=Ge.....
(You may be prompted at this point to log into the Redhat Portal, do that if necessary.)
The page will then show the text
Display Token
Click Display Token
It will show output similar to this:
Log in with this token
oc login --token=... --server=https://api.ca-central-1.starter.openshift-online.com:6443
On the web console, click in your profile and then you can see "copy Login command" like this:
Then you just click on it and do it again on the button "Display token" in the new browser tab. Here is what your token looks like:
I just tried actually signing up for an OpenShift v3 Starter plan (which I hadn't done before because I didn't want to get ahead of myself, and the migration guide hadn't said to do so yet). That course of action did give me access to the "Command Line Tools" menu item under the ? menu, which gives the command line as oc login https://api.starter-us-east-1.openshift.com --token=<hidden>. (The hidden token is copied to the clipboard if you click the clipboard icon to the right of that line.)
I created an account for OpenShift v3 Starter plan.
Then I installed OC Tool available here.
I created a project called spike1 on US west.
Finally when running oc login and set Server URL to https://console.starter-us-west-1.openshift.com/
Hope this helps.
Once you create a project in public OpenShift. It redirect to my console
starter-us-west-1.openshift.com/console/
If you wana login to openshift using CLI.
command is
oc login https://console.starter-us-west-1.openshift.com

Selenium/Chrome - Launch w/ Profile, save no data

Initiating driver with selenium without any arguments on the profile will lead you to clean chrome profile: nothing added, copied,synced, logged, installed.
When you load a profile - it starts using it like it's a default profile - it loads whatever it has , have all installed stuff. But it also SAVES data.
Is there a way to launch a profile with Selenium/Chrome but save NOTHING to it, so it will beused like an empty profile - Launched, used, all changes discarded, launch again and have nothing changed?
INCOGNITO Doesn't work as it blocks some features.(e.g several extensions cannot be interacted with when you are in incognito)
There are two possible options that I can think of
Copy the profile
One is to have a copy of the profile and use that to load the browser
So /profiles/common_profile has your profile and when you want to launch chrome your will create a copy of the same to /profiles/browser_profile
Use git in profile
You can do below in your default profile
git init
git add .
git commit -m "Default profile"
After the browser is done you can do a
git reset --hard

How to symbolicate crashes in Xcode 7.3?

Can you help me get my crashes symbolicated?
In Xcode 7.3, Window -> Organizer -> Crashes, I have crash reports from my latest TestFlight builds. They were built on this Mac, and all the archives with the corresponding dSYMs are in the Archives tab. The app is divided into a number of frameworks and the main app, and many are a mix of Swift and Objective C. In the crash log I can see the name of the frameworks and app listed correctly, but all the entries for my frameworks and app are in hex. UIKit is symbolicated just fine.
When I look in iTunes Connect, it says "Yes" to "Includes Symbols" and allows me to download the dSYMs. When building, the "Debug Information Format" option was set to "DWARF with dSYM". I tried setting "Strip Debug Symbols During Copy"
and "Strip Linked Product" to "No" to see if that made a difference. It didn't.
I cannot find the symbolicatecrash app on my system, not even in /usr/bin or /Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/A/Resources/symbolicatecrash, but I have an older Xcode 5 where I could grab it. However, it does not resolve the symbols anymore.
I have the same problem in Instruments, if I profile my app, UIKit is symbolicated just fine, but my frameworks and app only show hex.
I know there have been a lot of posts about this, but I have going through them a lot from the 7.3 beta period and until now and have not found a solution
The location of symbolicatecrash has changed in Xcode 7.3:
/Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
After reading this:
https://developer.apple.com/library/content/technotes/tn2151/_index.html
you find out that the App Store is responsible for symbolicating crash reports that come from TestFlight – not Xcode. And it appears the App Store is very unreliable at doing it.
Here's a workaround.
Go to the Archives tab in the "Organizer" window and make sure that for whatever build you need to symbolicate a crash report for, you have clicked the "Download dSYMS..." button over on the right side of the page. This is required if you are uploading in BitCode.
Attach an iOS device so that it appears in the "Devices" window.
Select the device and click "View Device Logs".
Now, go back to the Organizer Window, select the "Crashes" tab and select one of the crashes that did not get symbolicated.
Right-click on it and select "Show in Finder".
Right-click on the revealed .xccrashpoint bundle and select "Show Package Contents".
Drill down into DistributionInfos -> all -> Logs.
Drag any of the .crash files into the left side of the "View Device Logs" pane open in the Devices window.
Wait a second or two for Xcode to symbolicate the crash.
Same here. Having a hard time finding the symbolicatecrash after upgrading to 7.3.
However, you can still use the atos though.
You can find the tutorial here Symbolicate crash in iOS8 with Xcode 6 .1
I do not upload symbols with my application, so the App Store cannot symbolicate for me. I used the following workaround to symbolicate all of the crashlogs that XCode downloads from the store. These instructions are for XCode 8. The paths for the symbolicate crash app will vary from version to version of XCode but the ideas should be the same in each version.
Place your symbols where the symbolicator can find them: Place your symbols (.dsym) file in your Archives directory. You can find this by going to Organizer, context clicking on an archive and choosing "show in finder". Navigate up to the Archives directory (e.g. /Users/USERNAME/Library/Developer/Xcode/Archives) and place your dsym file there. It can be in other locations as well, it's just that I've verified that this one works.
Download the crash logs: In XCode, make sure that you've downloaded the crashlogs for the build you want to symbolicate (Organizer->Crashes, click on your app and then choose the version of your app in the panel to the right of the list of apps).
Locate the crash logs on disk: In the panel that has the App Version and build number, context click on one of the crashes and choose "Show in Finder". Navigate up to the "Crashes Folder" and note this location e.g.: /Users/USERNAME/Library/Developer/Xcode/Products/com.company-name.Your-App/VERSION/Crashes
Setup DEVELOPER_DIR for symbolicatecrash on the command line: Open a terminal window and CD to the crashes directory from step 3 and set the DEVELOPER_DIR like this: cd /Users/USERNAME/Library/Developer/Xcode/Products/com.companyname.Your-App/VERSION/Crashes/
export set DEVELOPER_DIR=/Applications/Xcode.app/Contents/Developer
(this should be the location of the "Developer" directory inside of your XCode app bundle).
Locate the symbolicatecrash script: symbolicatecrash knows how to find your symbolicate crash logs using the dsym from step 1. Apple moves it around from version to version of xcode. You can find it like this: find /Applications/Xcode.app/ -name symbolicatecrash. In XCode 8, it is in /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash
Backup your crashes folder You may want to backup your crashes folder (/Users/USERNAME/Library/Developer/Xcode/Products/com.companyname.Your-App/VERSION/Crashes/)
Symbolicate all of your crashes: Be sure that you are still in the Crashes directory from step 4 and type
for i in `find . -type f -name \*.crash`; do cat $i | /Applications/Xcode.app/Contents/SharedFrameworks/DVTFoundation.framework/Versions/A/Resources/symbolicatecrash --output $i.sym; mv $i.sym $i; done;
This symbolicates each .crash file into an output file and then copies that back over the original, unsymbolicated file.
View Crashes Return to the crashes organizer and view the symbolicated crashes
I tried to copy symbolicatecrash file from xCode 7.2 and pasted it in xCode 7.3 in the following path:
/Applications/Xcode.app/Contents/SharedFrameworks/DTDeviceKitBase.framework/Versions/Current/Resources/
Am using Crasher script to symbolicate the crash reports How to use Crasher
According to the documentation of Xcode 9.0:
The Crashes Organizer symbolicates unsymbolicated logs, if they are
selected, using a local .dSYM indexed by Spotlight. (22550064)
You can check out more on this in Xcode's Documentation.

How to create a Chrome profile programmatically?

Development, testing, staging environments are controlled via different proxy servers in my setup. I want to script creation of multiple Chrome profiles (sometimes called "user" or "person") and connect to a different proxy server for each of them. Finally I want to share this script with colleagues so that they have access to the exactly same setup.
The latter can be done via scripted installation of extensions such as Falcon Proxy or Proxy Helper to the Chrome profile. I would like to know how to script creation of the different profiles.
A profile is a folder inside ~/.config/google-chrome (Linux, ~/Library/Application Support/Google/Chrome (Mac OS X) and %USERPROFILE%\AppData\Local\Google\Chrome\User Data (Windows). But how to create and initialize one? Where do I register the new profile?
Creating a user
The following example applies to Windows, but the basic procedure should be the same.
First, change to the UserData folder in your Chrome installation:
cd "%APPDATA%\..\Local\Google\Chrome\User Data"
This method will copy the current user as a template for the new user. If the new user should be blank, you need to delete (CTRL + SHIFT + DEL the current browser data).
Now create a new user:
mkdir NewUser && copy Default NewUser
Change your directory to the chrome installation:
cd "C:\Program Files (x86)\Google\Chrome\Application"
Factory-Reset all user parameters:
chrome.exe --user-data-dir="..\User Data\NewUser" -first-run
where --user-data-dir is the path (full or relative) to the previously created NewUser directory.
Running as NewUser
To run chrome again using this profile, simply run chrome without the -first-run flag.
From this documentation, I finally found a way to create a user/person, rather than a separate profile. The difference is especially important in Mac OS X since different profiles can be opened concurrently using the same Chrome process.
/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome --args --profile-directory="StagingEnv" --first-run
The only unfortunate fact is that this new person doesn't inherit the name from the profile directory. Instead, it is always called Person X where X is an increment number.
I need to go to the Local State file to change it.
grep -o '"StagingEnv":{[^}]*}' ~/Library/Application\ Support/Google/Chrome/Local\ State
"StagingEnv":{"active_time":1437709453.172762,"avatar_icon":"chrome://theme/IDR_PROFILE_AVATAR_6","background_apps":false,"is_ephemeral":false,"is_omitted_from_profile_list":false,"is_using_default_avatar":true,"is_using_default_name":true,"managed_user_id":"","name":"<b>Person 3</b>","user_name":""}
This file is overridden when Chrome quits, so I need to kill Chrome, change the file and run Chrome again.
I think the easiest way to create multiple chrome profile is
On your computer, open Chrome.
At the top right, click Profile.
Click Manage people.
Click Add person.
Choose a name and a photo/picture.
Select Create a short cut on the desktop.
Click Save. A new window will open and ask you to turn on sync which is
optional.
By this, each chrome profile will be created and you can check on C:\Users\youname\AppData\Local\Google\Chrome\User Data.

Jenkins won't execute correctly a command from a .bat

I have set up Jenkins so that it builds my project, runs some tests and then creates an HTML page containing a report.
I made a .bat file to open the html report in my browser. There is just one line in that .bat file :
"E:\user\Visual Studio 2010\JenkinsWorkspace\JobTest\index.html"
When I run that .bat in a prompt myself, the page index.html is open (so it works).
But the problem is that when I set up a Jenkins' job to run that .bat, nothing happens.
The job gets stuck after calling the .bat and never finishes.
Any idea why?
Note: I have other .bat (that do not open html pages) that are successfully executed by Jenkins.
EDIT: here is the errors I get in the prompt log from Jenkins's menu :
C:\Program Files\Jenkins\jobs\JobTest2_enUnSeulScript\workspace>echo "
Opening html page" " >> Opening html page"
C:\Program
Files\Jenkins\jobs\JobTest2_enUnSeulScript\workspace>"C:\Program
Files\Google\Chrome\Application\chrome.exe" "E:\user\Visual
Studio 2010\JenkinsWorkspace\JobTest\testResults.14h05m15s65ms.11.04.2013.trx.htm"
[688:3900:0411/140520:ERROR:gpu_info_collector_win.cc(96)] Can't
retrieve a valid WinSAT assessment.
[688:3900:0411/140520:ERROR:process_singleton_win.cc(540)] Lock file
can not be created! Error code: 32
[688:3900:0411/140520:ERROR:chrome_browser_main.cc(1157)] Failed to
create a ProcessSingleton for your profile directory. This means that
running multiple instances would start multiple browser processes
rather than opening a new window in the existing process. Aborting now
to avoid profile corruption.
Build step 'Exécuter une ligne de commande batch Windows' marked build as failure [htmlpublisher]
Archiving HTML reports... [htmlpublisher] Archiving at PROJECT level
E:\user\Visual Studio 2010\JenkinsWorkspace\JobTest to C:\Program
Files\Jenkins\jobs\JobTest2_enUnSeulScript\htmlreports\HTML_Tests_Report
Finished: FAILURE
If you are running Jenkins as a Window's service, you will probably need to enable the service to interact with the desktop. Do the following:
Open the Services module
Right-click on Jenkins and select "Properties"
On the "Log On" tab, run as "Local System account" and select the "Allow service to interact with desktop" checkbox
-- OR --
You can run Jenkins via the command-line. Ie: "java -jar jenkins.war".
I am guessing that your Jenkins install is running as a Windows Service. When Jenkins is run as a service on a Windows machine it runs under the System account, not a user account. The System account usually does not have the same settings as a user account.
You might want to try starting a CMD shell as the System Account. (The answers to this question should help you with that: How Do You Run CMD under System Account.) From there, try running the batch file and see what happens. You may find that you need to setup somethings like the PATH before it works.
I know this is late, but I just answered another question on how to open an .exe (or .bat) from Jenkins's service on Windows
Open Excel on Jenkins CI
The issue is that while your command actually works, it does that in Session 0 (which is the session of Local System user that launched your Jenkins service), which you cannot see while being logged in through your own user account, most likely in Session 1.
Hope this helps