Search by

Run your first test

BrowserStack App Automate enables you to test native and hybrid mobile applications using Appium automation framework. Its easy to run your Appium tests using NUnit on real Android and iOS devices on BrowserStack. This guide will help you get started with your first test.

1. Setup

Ensure you have NUnit libraries i.e Nunit and NUnit3TestAdapter installed. This can be achieved using the NuGet Gallery.

# Install NUnit and NUnit3TestAdapter using the NuGet Gallery

2. Upload your app

Upload your Android app (.apk or .aab file) or iOS app (.ipa file) to BrowserStack servers using our REST API. Here is an example cURL request to upload the app :

curl -u "YOUR_USERNAME:YOUR_ACCESS_KEY" \
-X POST "https://api-cloud.browserstack.com/app-automate/upload" \
-F "file=@/path/to/app/file/Application-debug.apk"

A sample response for the above request is shown below:

{
    "app_url":"bs://j3c874f21852ba57957a3fdc33f47514288c4ba4"
}

Note the value of app_url returned in the API response (bs://j3c874f21852b..... in the above example). This value will be used later to set the app capability to specify application under test in your Appium test scripts.

Note:
  1. App upload will take a few seconds to about a minute depending on the size of your app. Do not interrupt the cURL command until you get the response back.
  2. If you upload an iOS app, we will re-sign the app with our own provisioning profile to be able to install your app on our devices during test execution.

3. Setup and run your test

In this step, you will learn how to configure your Appium test script using desired capabilities to test remotely on BrowserStack’s real device cloud. Here is a sample test case written for running with NUnit.

If you are using our Sample App, the sample test below will install the Sample App (Wikipedia App) on the device, search for ‘browserstack’ and asserts for the list of results. If you are using your own app, modify the code as per your test cases. Copy the code below into your editor, and run the test from the command-line interface.

namespace android
{
  [TestFixture("single","galaxy-s6")]
  public class SingleTest : BrowserStackNUnitTest
  {
    public SingleTest(string profile, string device) : base(profile,device){}

    [Test]
    public void searchWikipedia()
    {
      AndroidElement searchElement = (AndroidElement)new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementToBeClickable(MobileBy.AccessibilityId("Search Wikipedia")));
      searchElement.Click();
      AndroidElement insertTextElement = (AndroidElement)new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementToBeClickable(By.Id("org.wikipedia.alpha:id/search_src_text")));
      insertTextElement.SendKeys("BrowserStack");
      Thread.Sleep(5000);

      ReadOnlyCollection<AndroidElement> allProductsName = driver.FindElements(By.ClassName("android.widget.TextView"));
      Assert.True(allProductsName.Count > 0);
    }
  }
}

If you are using our iOS Sample App, the sample test below will install the Sample App (BStackSample App) on the device, navigate to the Login screen, enters the login email and check whether the email is registered on WordPress. If you are using your own app, modify the code as per your test cases. Copy the code below into your editor, and run the test from the command-line interface.

namespace ios
{
    [TestFixture("single", "iphone-7")]
    public class SingleTest : BrowserStackNUnitTest
    {
        public SingleTest(string profile, string environment) : base(profile, environment) { }

        [Test]
        public void textVerificationTest()
        {
            IOSElement textButton = (IOSElement)new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementToBeClickable(MobileBy.AccessibilityId("Text Button")));
            textButton.Click();

            IOSElement textInput = (IOSElement)new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementToBeClickable(MobileBy.AccessibilityId("Text Input")));
            textInput.SendKeys("hello@browserstack.com"+"\n");

            IOSElement textOutput = (IOSElement)new WebDriverWait(driver, TimeSpan.FromSeconds(30)).Until(ExpectedConditions.ElementToBeClickable(MobileBy.AccessibilityId("Text Output")));
            Assert.Equals(textOutput.Text,"hello@browserstack.com");
        }
    }
}

To actually run the test case, we need to integrate with BrowserStack as follows:

Integration with BrowserStack

Note: Running your NUnit tests on BrowserStack requires a username and an access key.

Integration of NUnit with BrowserStack is made possible by the use of the following module:

namespace android
{
    public class BrowserStackNUnitTest
    {
        protected AndroidDriver<AndroidElement> driver;
        protected string profile;
        protected string device;
        private Local browserStackLocal;

        public BrowserStackNUnitTest(string profile, string device)
        {
                this.profile = profile;
                this.device = device;
        }

        [SetUp]
        public void Init()
        {
            NameValueCollection caps = ConfigurationManager.GetSection("capabilities/" + profile) as NameValueCollection;
            NameValueCollection devices = ConfigurationManager.GetSection("environments/" + device) as NameValueCollection;

            DesiredCapabilities capability = new DesiredCapabilities();

            foreach (string key in caps.AllKeys)
            {
                capability.SetCapability(key, caps[key]);
            }

            foreach (string key in devices.AllKeys)
            {
                capability.SetCapability(key, devices[key]);
            }

            String username = Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME");
            if (username == null)
            {
                username = ConfigurationManager.AppSettings.Get("user");
            }

            String accesskey = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
            if (accesskey == null)
            {
                accesskey = ConfigurationManager.AppSettings.Get("key");
            }

            capability.SetCapability("browserstack.user", username);
            capability.SetCapability("browserstack.key", accesskey);

            String app = Environment.GetEnvironmentVariable("BROWSERSTACK_APP_ID");
            if (app != null)
            {
              capability.SetCapability("app", app);
            }

            if (capability.GetCapability("browserstack.local") != null && capability.GetCapability("browserstack.local").ToString() == "true")
            {
                browserStackLocal = new Local();
                List<KeyValuePair<string, string>> bsLocalArgs = new List<KeyValuePair<string, string>>() {
                        new KeyValuePair<string, string>("key", accesskey)
                };
                browserStackLocal.start(bsLocalArgs);
            }

            driver = new AndroidDriver<AndroidElement>(new Uri("https://" + ConfigurationManager.AppSettings.Get("server") + "/wd/hub/"), capability);
        }

        [TearDown]
        public void Cleanup()
        {
            driver.Quit();
            if (browserStackLocal != null)
            {
                browserStackLocal.stop();
            }
        }

    }
}

The module reads from config file where you need to put the BrowserStack Hub URL and credentials. Also, remember to update the app in the above module using the app_url(bs://…..) which was obtained after uploading the App to the BrowserStack cloud in Step 2. If the BROWSERSTACK_USERNAME, BROWSERSTACK_ACCESS_KEY and BROWSERSTACK_APP_ID are set in Environment variables, then they will take a preference.

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="capabilities">
      <section name="single" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <section name="local" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <section name="parallel" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </sectionGroup>
    <sectionGroup name="environments">
      <section name="galaxy-s6" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <section name="galaxy-s7" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <section name="pixel" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </sectionGroup>

  </configSections>

  <appSettings>
    <add key="user" value="YOUR_USERNAME" />
    <add key="key" value="YOUR_ACCESS_KEY" />
    <add key="server" value="hub-cloud.browserstack.com" />
  </appSettings>

  <capabilities>
    <single>
      <add key="build" value="nunit-browserstack" />
      <add key="name" value="single_test" />
      <add key="browserstack.debug" value="true" />
      <add key="app" value="bs://hashed-app-id"/>
    </single>
  </capabilities>

  <environments>
        <galaxy-s6>
            <add key="device" value="Samsung Galaxy S6"/>
        </galaxy-s6>
        <galaxy-s7>
            <add key="device" value="Samsung Galaxy S7"/>
        </galaxy-s7>
        <pixel>
            <add key="device" value="Google Pixel"/>
        </pixel>
    </environments>
</configuration>
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <sectionGroup name="capabilities">
      <section name="single" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <section name="local" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <section name="parallel" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </sectionGroup>
    <sectionGroup name="environments">
      <section name="iphone-7" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
      <section name="iphone-7-plus" type="System.Configuration.AppSettingsSection, System.Configuration, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
    </sectionGroup>
  </configSections>

  <appSettings>
    <add key="user" value="YOUR_USERNAME" />
    <add key="key" value="YOUR_ACCESS_KEY" />
    <add key="server" value="hub-cloud.browserstack.com" />
  </appSettings>

  <capabilities>
    <single>
      <add key="build" value="nunit-browserstack" />
      <add key="name" value="single_test" />
      <add key="browserstack.debug" value="true" />
      <add key="app" value="bs://hashed-app-id"/>
    </single>
  </capabilities>

  <environments>
    <iphone-7>
      <add key="device" value="iPhone 7"/>
    </iphone-7>
    <iphone-7-plus>
      <add key="device" value="iPhone 7 Plus"/>
    </iphone-7-plus>
  </environments>

</configuration>

Run your test on BrowserStack using the following:

Build the solution in Visual Studio
Run test with fixture "single" from Test Explorer
Note: Refer to our GitHub repository for a complete example: BrowserStack - NUnit

4. Viewing test results

You can access results of your test sessions on the App Automate dashboard as well as using our REST API. You can drill down into the details of a specific test session to view its execution details and debugging information such as video recording, network logs and device logs.