EarlGrey
EarlGrey copied to clipboard
How to restart app before every test case and test suite in EarlGrey?
Hi all, I have a question. I want to restart app like in XCUITests before each test case in EarlGrey. As far as I searched I found that I need to call a function via AppDelegate.
And I copy the contents of applicationWillTerminate(_ application: UIApplication) to the newly written restartAppForTesting(with appDelegate: AppDelegate) function. And call this function in tearDown() method of my test suite like below:
import EarlGrey
override func setUp() {
super.setUp()
}
override func tearDown() {
super.tearDown()
let appDelegate: AppDelegate = UIApplication.shared.delegate as! AppDelegate
//This function is same with the applicationWillTerminate(_ application: UIApplication)
appDelegate.restartAppForTesting(with: appDelegate)
// wait for app restarts
sleep(20)
}
func testTesCase1() {
//Test logic
}
func testTestCase2() {
//Test logic
}
However I get an error before testTestCase2() is being executed. The error is: test runner exited with code 1 before finishing running test
What can I do? Is there a proper way for me to restart app before each test case and test suite? Thanks in advance!
Earlgrey 1 doesn’t support this feature. You should use Earlgrey 2 which is built on top of XCUITest and allows launching and terminating app by calling xcuiapplication methods directly.
Thank you for replying @khandpur. From the link here https://github.com/google/EarlGrey/blob/2.0.0/docs/setup.md EarlGrey 2.0 does not have Cocoapods support. Is that means everyone in the project should set up EarlGrey manually, right?
@tirodkar fyi
@selin194 EarlGrey 2.0 has support for black-box testing with instructions over here.
https://github.com/google/EarlGrey/blob/earlgrey2/docs/cocoapods-setup.md
I'll add a link to it in the setup doc. Thanks! Tell me if you run into issues.
Hey @tirodkar ! I install EarlGreyApp and EarlGreyTest pods to our project. However EarlGrey.swift file is not installed as in EarlGrey pod. Do I miss something? Additionally, do I need to import EarlGreyTest , right? (By the way I already execute gem install earlgrey)
Edit: I added EarlGrey.swift file manually, after that I tried to write a simple test case like below:
import XCTest
import EarlGreyTest
class AccessibilityTests: XCTestCase {
private var closeIconMatcher = grey_accessibilityID("closeIcon")
override func setUp() {
super.setUp()
continueAfterFailure = false
XCUIApplication().launch()
}
override func tearDown() {
super.tearDown()
}
func testExample() {
EarlGrey.selectElement(with: closeIconMatcher)
.perform(grey_tap())
}
}
and I get an error that says: Host background port not assigned. Application under test may have failed to launch and/or does not link to EarlGrey's AppFramework.
Here is my Podfile:
target 'myApp' do
// My other pods
pod 'EarlGreyApp'
end
target 'AccessibilityEarlGrey2' do
inherit! :search_paths # Required for not double-linking libraries in the app and test targets.
pod 'EarlGreyTest'
end
Do I need to add something? Thank you!
@selin194 Did you get the solution? I am also getting the same console log.
"Host background port not assigned. Application under test may have failed to launch and/or does not link to EarlGrey's AppFramework."
@tirodkar do you have any insight?
@anshulpara I do not find a solution, do you have any idea about this?
I haven't added gem support for EarlGrey 2.0 yet. Can you drag / drop EarlGrey.swift into your folder?
https://github.com/google/EarlGrey/blob/earlgrey2/TestLib/Swift/EarlGrey.swift
I will try this, I guess I was adding the wrong version of this file.
Hi @selin194, did it work for you? I have the same issue.
I have the same issue too, have you fix it @maroleks @selin194 ?
Hey @maroleks and @CblPOB. I have not tried this yet. Are you trying https://github.com/google/EarlGrey/blob/earlgrey2/TestLib/Swift/EarlGrey.swift this file, right?
@selin194 yes, i have it in my folder already and it seems that it haven't affect this issue
@CblPOB, @selin194 same here... same file and same (or no-) result
@selin194 , @CblPOB and @maroleks : I was also getting same error:
"Host background port not assigned. Application under test may have failed to launch and/or does not link to EarlGrey's AppFramework."
When I looked into Xcode console logs, there was an error (which actually was ignored and the app was launched) related to AppFramework signing in start. I had this issue because my App and the UI Testing bundles were signed by different team ids due to which iOS was not loading the AppFramework. Once I enabled signing using same team id, I was able to run the tests comfortably with EarlGrey.
Note: I faced this issue on real device.
Thanks for sharing your knowledge @Ad1991! Can you now restart the app using EarlGrey 2.0 by updating team IDs?
@selin194: Well, I was getting this issue at first launch itself:
"Host background port not assigned. Application under test may have failed to launch and/or does not link to EarlGrey's AppFramework."
Which I fixed using the mechanism I in comment mentioned above. However, since you mentioned of restart, when I tried to restart using terminate() and launch() methods of XCUIApplication, I noticed that I am now getting the same error at second launch. When I looked into logs of the application (not runner application) I found out that system was not able to inject the AppFramework library at second launch:
"dyld: warning: could not load inserted library '@executable_path/Frameworks/AppFramework.framework/AppFramework,@executable_path/Frameworks/AppFramework.framework/AppFramework' into hardened process because image not found"
I was a bit confused at start as to why system would load same library at first launch but not in subsequent launches. Then I noticed the library path it was loading and I would see that AppFramework path was duplicated. I looked up and found this code (XCUIApplication+GREYEnvironment.m:26):
- (void)grey_configureApplicationForLaunch {
NSMutableDictionary *mutableEnv = [self.launchEnvironment mutableCopy];
NSString *insertionKey = @"DYLD_INSERT_LIBRARIES";
NSString *insertionValue = @"@executable_path/Frameworks/AppFramework.framework/AppFramework";
NSString *alreadyExistingValue = [mutableEnv valueForKey:insertionKey];
if (alreadyExistingValue) {
//Below is the line causing library path to be duplicated.
insertionValue = [NSString stringWithFormat:@"%@,%@", alreadyExistingValue, insertionValue];
}
[mutableEnv setObject:insertionValue forKey:insertionKey];
self.launchEnvironment = [mutableEnv copy];
}
See the comment inside if case. If you change that code to as below, it should launch second time properly as well:
if (alreadyExistingValue && ![alreadyExistingValue containsString:insertionValue]) {
insertionValue = [NSString stringWithFormat:@"%@,%@", alreadyExistingValue, insertionValue];
}
@tirodkar : I hope the above is useful for you as well.