Front End

21 jun, 2018

Rodando testes em paralelo com Appium, Selenium Grid e Java – Parte 01

Publicidade

Estive estudando um pouco sobre como rodar testes em paralelo, e a minha maior curiosidade era saber como poderia executá-los em diferentes tipos de plataforma, mas para isso, tive que entender e estudar o funcionamento de algumas ferramentas antes.

Então, nesta série, quero compartilhar minha experiência com vocês, fazendo um artigo um pouco mais mastigado para que não tenham tantos problemas quanto eu. Mas fique sabendo desde agora que testar em paralelo não é um bicho de sete cabeças.

Ferramentas para a configuração inicial dos testes:

Let’s go!

Configuração Inicial

Vamos, primeiramente, criar o nosso projeto de testes. Abra a sua IDE e crie um projeto Maven (no meu caso, vou usar o Eclipse):

File > New > Maven > Maven Project (Eclipse).

Escolha maven-archetype-quickstart 1.1 para gerar um projeto o mais simples possível.

Perfeito, agora vamos no nosso arquivo pom.xml para adicionar todas as dependências e plugins que vamos usar em nosso projeto.

  • Java-Client Appium
<dependency>
  <groupId>io.appium</groupId>
  <artifactId>java-client</artifactId>
  <version>4.1.2</version>
</dependency>
  • Surefire Maven Plugin
<build>
  <plugins>
    <plugin>
      <groupId>org.apache.maven.plugins</groupId>
      <artifactId>maven-surefire-plugin</artifactId>
      <version>2.19.1</version>
    </plugin>
  </plugins>
</build>

Lembrando que neste projeto, já vem setado o jUnit. Logo, temos que alterar somente a versão dele para 4.7.

  • jUnit 4
<dependency>
  <groupId>junit</groupId>
  <artifactId>junit</artifactId>
  <version>4.7</version>
  <scope>test</scope>
  </dependency>
</dependencies>

Depois da configuração do pom.xml, vamos criar um diretório no qual vamos colocar os nossos apps.

File > New > Folder > [folder-name].

Vou colocar aqui também os arquivos dos apps para download:

Faça o download deles e jogue na pasta que você acabou de criar.

Criação das Classes

Ufa! Depois de todas essas configurações, podemos começar a criar nossas classes. A ideia é utilizar o padrão Page Object em nossos testes e vamos testar também aplicações semelhantes, nas quais a aplicação iOS tem as mesmas funcionalidades que a aplicação Android.

Dentro da nossa estrutura src/test/java/meu-pacote-de-tests, já existe uma classe de teste que foi criada junto com a nossa estrutura (pode excluir ela!).

Agora vamos criar um outro pacote que vai abrigar todas as nossas screens.

File > New > Package > [package-name].

E dentro desse pacote vamos criar a classe screen que vai contemplar todos os elementos da tela da nossa aplicação.

public class CalculatorScreen {

private AppiumDriver<MobileElement> driver;

public CalculatorScreen(AppiumDriver<MobileElement> driver)  {
	PageFactory.initElements( new AppiumFieldDecorator(driver), this);
	this.driver = driver;
  }

}

Esse é o início da nossa classe e a parte mais importante: o PageFactory, responsável por buscar todos os meus elementos em tela. Mas para isso, precisamos de uma instância do nosso driver e do contexto da page. Criamos o PageFactory no meu construtor porque sempre que criarmos uma instância da CalculatorScreen, ele vai buscar todos os seus elementos com o driver específico que recebermos no construtor. Agora vamos pegar os elementos da tela (não vou mostrar como fazer isso aqui e nem como configurar os emuladores, mas posso ajudar com links; já que existem diversas ferramentas para isso).

Configurando Emuladores

Inspetores de tela

Depois de pegar os elementos, podemos atualizar a nossa page. Agora temos esse resultado:

public class CalculatorScreen {

private AppiumDriver<MobileElement> driver;

public CalculatorScreen(AppiumDriver<MobileElement> driver)  {
	PageFactory.initElements( new AppiumFieldDecorator(driver), this);
	this.driver = driver;
}

  @AndroidFindBy(id = "android_button_sum")
	@iOSFindBy(accessibility = "apple-sum-button")
	public RemoteWebElement buttonSum;

  @AndroidFindBy(id = "android_result_text")
	@iOSFindBy(accessibility = "apple_result_text")
	private RemoteWebElement resultText;

  @AndroidFindBy(id = "android_field_first_number")
	@iOSFindBy(accessibility = "apple_first_input")
	private RemoteWebElement inputFirstNumber;

	@AndroidFindBy(id = "android_field_second_number")
	@iOSFindBy(accessibility = "apple_second_input")
	private RemoteWebElement inputSecondNumber;
}

Reparem nas annotations. Dentro delas especificamos qual vai ser o nosso locator, apesar de termos locators separados tanto do Android, quanto do iOS em apenas uma variável. Visivelmente não temos aquele findElement(By()). Consegue visualizar a abstração da nossa page?

Agora vamos finalizar a nossa classe criando os métodos com as ações da page.

public CalculatorScreen fillFirstNumber(String number) {
	inputFirstNumber.click();
	inputFirstNumber.clear();
	driver.getKeyboard().sendKeys(number);
	return this;
}

public CalculatorScreen fillSecondNumber(String number) {
	inputSecondNumber.click();
	inputSecondNumber.clear();
	driver.getKeyboard().sendKeys(number);
	return this;
}

public CalculatorScreen closeKeyboard() {
	driver.getKeyboard().pressKey(Keys.RETURN);
	return this;
}

public String operationResult() {
	return resultText.getText().toString().trim();
}

public void quitDriver() {
	driver.quit();
}

Beleza! Vamos criar as duas classes de teste para Android e iOS, dentro do pacote src/test/java/meu-pacote-de-tests.

Classe de teste Android

public class TestAndroidCalculator {

	private static CalculatorScreen calculatorScreen;
	private static AppiumDriver<MobileElement> appiumDriver;

	@BeforeClass
	public static void setup() throws MalformedURLException {
	  DesiredCapabilities capabilities = new DesiredCapabilities();
	  capabilities.setCapability("app",new File("apps/app-android-calculator.apk"));
	  capabilities.setCapability("platformName","Android" );
	  capabilities.setCapability("deviceName","Android Emulator API 22");
	  capabilities.setCapability("unicodeKeyboard", true);
	  capabilities.setCapability("disableAndroidWatchers" , true);
	  appiumDriver = new AndroidDriver<MobileElement>(new URL("http://localhost:4723/wd/hub") , capabilities);
	  calculatorScreen = new CalculatorScreen(appiumDriver);
	}

	@Test
	public void shouldSum() {
	  calculatorScreen.fillFirstNumber("10").fillSecondNumber("10").buttonSum.click();
	  assertTrue(calculatorScreen.operationResult().equals("20"));
	}

	@AfterClass
	  public static void teardown() {
	  calculatorScreen.quitDriver();
	}
}

Classe de teste iOS

public class TestIosCalculator {

	private static CalculatorScreen calculatorScreen;
	private static AppiumDriver<MobileElement> appiumDriver;

	@BeforeClass
	public static void setup() throws MalformedURLException {
	  DesiredCapabilities capabilities = new DesiredCapabilities();
	  capabilities.setCapability("app",new File("apps/SimpleCalculator.app"));
	  capabilities.setCapability("plataform", "MAC" );
	  capabilities.setCapability("plataformName", "ios" );
	  capabilities.setCapability("deviceName", "iPhone SE");
	  capabilities.setCapability("automationName" , "XCUITest");
	  appiumDriver = new IOSDriver<MobileElement>(new URL("http://localhost:4723/wd/hub") , capabilities);
	  calculatorScreen = new CalculatorScreen(appiumDriver);
	}

	@Test
	public void should_sum() {
	  calculatorScreen.fillFirstNumber("10").fillSecondNumber("10").closeKeyboard().buttonSum.click();
	assertTrue(calculatorScreen.operationResult().equals("20"));
	}

	@AfterClass
	public static void teardown() {
	  calculatorScreen.quitDriver();
	}
}

Os casos de teste são bem simples; estão apenas verificando se a aplicação está realizando corretamente o fluxo da soma. Especifiquei também o capabilities de cada dispositivo e vou deixar um link aqui explicando o que faz com cada um.

Show! Agora já podemos rodar os testes. Inicie seu emulador Android (não precisa iniciar o simulador iOS) e inicie o Appium, como de costume, com o comando:

$ appium

Pronto! Agora é só rodar os testes. Para isso, vamos aproveitar e usar o Maven, que temos que rodar dentro do diretório AndroidAndIosTesteParaleloComAppium/, executando o comando:

$ mvn clean test

E então:

Foi executado um teste de cada vez.

No próximo artigo vou focar em como fazer a nossa estrutura atual rodar em paralelo no Selenium Grid. Obrigado!

Referências

***

Este artigo foi publicado originalmente em: https://www.concrete.com.br/2018/04/25/rodando-testes-em-paralelo-com-appium-selenium-grid-e-java-parte-i/