Running AltTester-based C# Tests on BrowserStack App Automate

If you wish to run automated tests using AltTester Unity SDK on various mobile devices on BrowserStack cloud service, then this article is for you. We have prepared a set of instructions that you can follow in order to successfully run tests on BrowserStack App Automate, as well as an example repository to guide you through. Check it out!

What is BrowserStack App Automate?

BrowserStack App Automate is a cloud-based testing platform that allows developers and testers to perform automated testing of mobile applications on a wide range of real devices. Among the platform’s key features you’ll find the following:

  • Compatibility testing: It helps verify the compatibility of mobile applications on different devices and platforms.
  • Functionality testing: The platform allows for thorough testing of application functionality.
  • Performance testing: Developers can assess the performance of their applications under various conditions.

In this automation process, BrowserStack uses a set of Appium capabilities to customize and configure the testing environment to match various scenarios. The term “capabilities” refers to the settings and options that you can specify when setting up a testing session, for example:

  • Device name: Specifies the device on which the application will be tested.
  • Operating system: Defines the target operating system for testing.
  • Access key: Provides secure access to the testing environment.

BrowserStack doesn’t support server side testing, meaning that the test folder can’t be uploaded onto the platform in order to run the tests. This article describes client side testing.

What is client side testing?

Client side testing generally focuses on testing the application or website directly on the user’s end. For testing carried on cloud services, this means that the test suite is stored locally, on a computer and connected to a device in the cloud.

A bit of context about the test project

For this integration we used as an example the C# tests written for TrashCat, one of Unity’s sample games that we instrumented with AltTester Unity SDK v2.0.1 and created builds for Android and iOS. The final repository is called EXAMPLES-CSharp-Cloud-Services-AltTrashCat and it is one of our many examples available on GitHub.

Running AltTester Unity SDK tests

Because our tests are written in C# using the NUnit framework, we used the Appium with NUnit section from the BrowserStack App Automate documentation to guide us through client side testing.

An important aspect of running tests on BrowserStack is that there’s a local testing connection needed. Local Testing, a BrowserStack option, allows us to conduct automated test execution for mobile apps that access resources hosted in development or testing environments. You’ll find the BrowserStackLocal setup below, at Step 5: Create and configure new file.

Prerequisites

  • Test suite – we used EXAMPLES-TrashCat-Tests
  • AltTester Desktop app installed for running AltServer
  • BrowserStack account – there is a free plan available that offers 100 min to run tests
  • .NET v5.0+ and NUnit v3.0.0+

Steps for running tests on Android an iOS builds

Step 1: Upload a test build of your app in BrowserStack and get the generated URL

There are two options for passing the build. You can upload the file (.apk or .ipa) from your local file system, as shown below, or use the BrowserStack REST API endpoint. To upload your app from local storage, use the UI button available on the Dashboard.

A unique app ID, formatted as bs://{app_id} will be generated if the upload was successful. Take note of this value because you will use it to specify the app capability for the application under test. The app is stored in your account and it doesn’t change if you upload the same build. You only need to do this once per build.

Step 2: Get BrowserStack credentials

Once you are logged into your BrowserStack account, you can find the credentials in the AccessKey section in the BrowserStack Dashboard.

Step 3: Set the BrowserStack credentials and app id as environment variables

To set these values as environment variables on Windows you can create a batch file on your local machine and run it every time you load your IDE. This will keep the sensitive information out of the repository. Here is an example:

set BROWSERSTACK_USERNAME "yourUsername" 
set BROWSERSTACK_ACCESS_KEY "yourAccessKey" 
set BROWSERSTACK_APP_ID_SDK_201="yourAppId"

Step 4: Install dependencies

In your code project, you need to install a Selenium WebDriver extension for Appium and C# Bindings for BrowserStack Local:

dotnet add package Appium.WebDriver --version 4.4.0 
dotnet add package BrowserStackLocal --version 2.3.0

Step 5: Create and configure new file

In your repository, create a new file that will hold the required settings for the integration. This file will hold all of the Appium and BrowserstackLocal settings that ensure the connection between the local environment and the cloud device. For future reference it will be called BaseTest. Every test file in this project inherits this C# class. In this file:

  • Access the environment variables set in the previous steps using the GetEnvironmentVariable method like so:
String BROWSERSTACK_USERNAME =Environment.GetEnvironmentVariable("BROWSERSTACK_USERNAME"); 
String BROWSERSTACK_ACCESS_KEY = Environment.GetEnvironmentVariable("BROWSERSTACK_ACCESS_KEY");
String BROWSERSTACK_APP_ID_SDK_201 = Environment.GetEnvironmentVariable("BROWSERSTACK_APP_ID_SDK_201");
  • Configure Appium capabilities and BrowserStack options

At this step you pass information to BrowserStack that configures the test environment as well as organize the test runs, such as your access credentials for the authentication, the cloud device/s you want to use, local tunnel settings and session details (e.g. project name). BrowserStack offers a capabilities builder, which helps you determine what settings you need and how to format them correctly. Example:

AndroidiOS
AppiumOptions capabilities = new AppiumOptions(); Dictionary<string, object> browserstackOptions = new Dictionary<string, object>(); browserstackOptions.Add("projectName", "TrashCat"); browserstackOptions.Add("buildName", "TrashCat201Android"); browserstackOptions.Add("sessionName", "tests - " + DateTime.Now.ToString("MMMM dd - HH:mm")); browserstackOptions.Add("local", "true"); browserstackOptions.Add("userName", BROWSERSTACK_USERNAME); browserstackOptions.Add("accessKey", BROWSERSTACK_ACCESS_KEY); capabilities.AddAdditionalCapability("bstack:options", browserstackOptions); capabilities.AddAdditionalCapability("platformName", "android"); capabilities.AddAdditionalCapability("platformVersion", "11.0"); capabilities.AddAdditionalCapability("appium:deviceName", "Samsung Galaxy S21"); capabilities.AddAdditionalCapability("appium:app", BROWSERSTACK_APP_ID_SDK_201);AppiumOptions capabilities = new AppiumOptions(); Dictionary<string, object> browserstackOptions = new Dictionary<string, object>(); browserstackOptions.Add("projectName", "TrashCat"); browserstackOptions.Add("buildName", "TrashCat201iOS"); browserstackOptions.Add("sessionName", "tests - " + DateTime.Now.ToString("MMMM dd - HH:mm")); browserstackOptions.Add("local", "true"); browserstackOptions.Add("userName", BROWSERSTACK_USERNAME); browserstackOptions.Add("accessKey", BROWSERSTACK_ACCESS_KEY); capabilities.AddAdditionalCapability("bstack:options", browserstackOptions); capabilities.AddAdditionalCapability("platformName", "ios"); capabilities.AddAdditionalCapability("platformVersion", "16"); capabilities.AddAdditionalCapability("appium:deviceName", "iPhone 14"); capabilities.AddAdditionalCapability("appium:app", BROWSERSTACK_APP_ID_SDK_201);
  • Configure the local testing connection

Using the BrowserStackLocal package, you need to start the local testing connection. You can do this in the code like this:

browserStackLocal = new Local(); 
List<KeyValuePair<string, string>> bsLocalArgs = new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("key", BROWSERSTACK_ACCESS_KEY)
};
browserStackLocal.start(bsLocalArgs);

This local connection can also be started manually. You need to download the local binary from BrowserStack docs and run the .exe file from its path.

  • Start Appium Driver

In order to test remotely on BrowserStack, you need to use an instance of Appium Driver. For that, use the remote BrowserStack URL and your access credentials, which are stored inside the AppiumOptions variable named capabilities:

AndroidiOS
appiumDriver = new AndroidDriver<AndroidElement>(new Uri("https://hub-cloud.browserstack.com/wd/hub/"), capabilities);appiumDriver = new IOSDriver<IOSElement>(new Uri("https://hub-cloud.browserstack.com/wd/hub/"), capabilities);
  • Initialize AltDriver
altDriver = new AltDriver();
  • [iOS] Handle permission pop-up

While running your tests on iOS you might get a pop-up that asks for permission to connect to devices on the local network.

To accept this notification and give permission, use the following lines:

IWebElement ll = appiumDriver.FindElement(OpenQA.Selenium.By.Id("Allow")); 
ll.Click();
  • Add method to keep Appium alive

In this context, Appium is only used to install the application and access it on the BrowserStack test device. After that, AltTester SDK picks up the connection and carries out the tests. 

An issue encountered in this example is that BrowserStack has a default idle timeout for Appium commands of 90 seconds, and in this case, running the tests takes longer than that.

To solve this problem you should add an action that keeps Appium alive in the TearDown method of the framework to ensure that Appium is used after every test. Here is an example:

AndroidiOS
appiumDriver.GetDisplayDensity();appiumDriver.GetClipboardText();
  • OneTimeTearDown: Quit the Appium driver and stop the local tunnel

At the end of your tests, add these methods in order to quit the driver and stop the BrowserStack local connection:

[OneTimeTearDown]
public void DisposeAppium()
{
      Console.WriteLine("Ending");
      appiumDriver.Quit();
      
altDriver.Stop();
      if (browserStackLocal != null)
      {
            browserStackLocal.stop();
       }
}
  • Additional step: Increase the idle timeout to 300s

If you have tests that take more than 90 seconds to complete, you can also set the maximum timeout using BrowserStack options:

browserstackOptions.Add("idleTimeout", "300");

Step 6: Have AltTester Server running on local machine

One of the architectural changes from v2.0.0 is that the AltServer module is incorporated in AltTester Desktop. In order to be able to execute tests, you need to have the AltTester Desktop running so that the AltDriver from the tests can connect to the local server. You can download the free version from our website.

Step 7: Run the tests

Make sure AltTester Desktop is running, the environment variables are set and then trigger the test execution from the terminal with dotnet test. After a few seconds you’ll see that the session started on your Browserstack dashboard.

We hope that this tutorial will come in handy for those of you who want to run AltTester-based tests on BrowserStack cloud devices. This example is available on GitHub, so if you wish to see the full repository, check out EXAMPLES-CSharp-Cloud-Services-AltTrashCat.

We’re preparing an article about running AltTester-based C# tests on BrowserStack with GitHub Actions. If this topic piques your interest, keep an eye out! If you have any questions, you can always reach us on Discord. Don’t forget to check out our documentation for further information.

Subscribe to our newsletter

And get our best articles in your inbox

 Back to top

1 response to “Running AltTester-based C# Tests on BrowserStack App Automate

Leave a Reply

Your email address will not be published. Required fields are marked *