乐闻世界logo
搜索文章和话题

How does Appium integrate with testing frameworks?

2月21日 16:19

Appium's test framework integration is a key component of building a complete automation testing system, supporting integration with multiple testing frameworks and toolchains. Here's a detailed explanation of Appium test framework integration:

Supported Testing Frameworks

1. Mocha

Mocha is a popular JavaScript testing framework:

javascript
const { describe, it, before, after, beforeEach, afterEach } = require('mocha'); const { Builder, By, until } = require('selenium-webdriver'); const assert = require('assert'); describe('Appium Test with Mocha', () => { let driver; before(async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 5', app: '/path/to/app.apk' }; driver = await new Builder().withCapabilities(capabilities).build(); }); after(async () => { await driver.quit(); }); beforeEach(async () => { // Preparation before each test }); afterEach(async () => { // Cleanup after each test }); it('should submit form successfully', async () => { const element = await driver.findElement(By.id('submit_button')); await element.click(); const result = await driver.findElement(By.id('result_message')); const text = await result.getText(); assert.strictEqual(text, 'Success'); }); it('should display error message', async () => { const element = await driver.findElement(By.id('submit_button')); await element.click(); const result = await driver.findElement(By.id('error_message')); const text = await result.getText(); assert.strictEqual(text, 'Error'); }); });

2. Jest

Jest is a JavaScript testing framework developed by Facebook:

javascript
const { Builder, By, until } = require('selenium-webdriver'); describe('Appium Test with Jest', () => { let driver; beforeAll(async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 5', app: '/path/to/app.apk' }; driver = await new Builder().withCapabilities(capabilities).build(); }); afterAll(async () => { await driver.quit(); }); test('should submit form successfully', async () => { const element = await driver.findElement(By.id('submit_button')); await element.click(); const result = await driver.findElement(By.id('result_message')); const text = await result.getText(); expect(text).toBe('Success'); }); });

3. Jasmine

Jasmine is a Behavior Driven Development (BDD) testing framework:

javascript
const { Builder, By, until } = require('selenium-webdriver'); describe('Appium Test with Jasmine', () => { let driver; beforeAll(async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 5', app: '/path/to/app.apk' }; driver = await new Builder().withCapabilities(capabilities).build(); }); afterAll(async () => { await driver.quit(); }); it('should submit form successfully', async () => { const element = await driver.findElement(By.id('submit_button')); await element.click(); const result = await driver.findElement(By.id('result_message')); const text = await result.getText(); expect(text).toBe('Success'); }); });

4. TestNG (Java)

TestNG is a popular Java testing framework:

java
import org.testng.annotations.*; import org.openqa.selenium.*; import org.openqa.selenium.remote.DesiredCapabilities; import io.appium.java_client.AppiumDriver; import io.appium.java_client.MobileElement; public class AppiumTestWithTestNG { private AppiumDriver<MobileElement> driver; @BeforeClass public void setUp() throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability("platformName", "Android"); capabilities.setCapability("deviceName", "Pixel 5"); capabilities.setCapability("app", "/path/to/app.apk"); driver = new AppiumDriver<>(new URL("http://localhost:4723/wd/hub"), capabilities); } @AfterClass public void tearDown() { if (driver != null) { driver.quit(); } } @Test public void testSubmitForm() throws Exception { MobileElement element = driver.findElement(By.id("submit_button")); element.click(); MobileElement result = driver.findElement(By.id("result_message")); String text = result.getText(); assertEquals(text, "Success"); } }

5. PyTest (Python)

PyTest is a popular Python testing framework:

python
import pytest from appium import webdriver from selenium.webdriver.common.by import By @pytest.fixture def driver(): capabilities = { 'platformName': 'Android', 'deviceName': 'Pixel 5', 'app': '/path/to/app.apk' } driver = webdriver.Remote('http://localhost:4723/wd/hub', capabilities) yield driver driver.quit() def test_submit_form(driver): element = driver.find_element(By.ID, 'submit_button') element.click() result = driver.find_element(By.ID, 'result_message') text = result.text assert text == 'Success'

Continuous Integration Integration

1. Jenkins

groovy
pipeline { agent any stages { stage('Install Dependencies') { steps { sh 'npm install' } } stage('Run Appium Tests') { steps { sh 'npm run test:appium' } } stage('Generate Reports') { steps { sh 'npm run test:report' } } } post { always { junit 'test-results/**/*.xml' publishHTML([ allowMissing: false, alwaysLinkToLastBuild: true, keepAll: true, reportDir: 'test-results/html', reportFiles: 'index.html', reportName: 'Appium Test Report' ]) } } }

2. GitHub Actions

yaml
name: Appium Tests on: push: branches: [ main ] pull_request: branches: [ main ] jobs: test: runs-on: macos-latest steps: - uses: actions/checkout@v2 - name: Set up Node.js uses: actions/setup-node@v2 with: node-version: '16' - name: Install dependencies run: npm install - name: Start Appium Server run: npx appium & - name: Run Appium tests run: npm run test:appium - name: Upload test results uses: actions/upload-artifact@v2 if: always() with: name: test-results path: test-results/

3. GitLab CI

yaml
stages: - test appium_tests: stage: test image: node:16 before_script: - npm install script: - npx appium & - npm run test:appium artifacts: when: always paths: - test-results/ reports: junit: test-results/**/*.xml

Test Reports

1. Allure Report

javascript
const { Builder, By, until } = require('selenium-webdriver'); const allure = require('allure-commandline'); describe('Appium Test with Allure', () => { let driver; before(async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 5', app: '/path/to/app.apk' }; driver = await new Builder().withCapabilities(capabilities).build(); }); after(async () => { await driver.quit(); }); it('should submit form successfully', async () => { allure.step('Click submit button', async () => { const element = await driver.findElement(By.id('submit_button')); await element.click(); }); allure.step('Verify result', async () => { const result = await driver.findElement(By.id('result_message')); const text = await result.getText(); assert.strictEqual(text, 'Success'); }); }); });

2. Mochawesome

javascript
const { Builder, By, until } = require('selenium-webdriver'); describe('Appium Test with Mochawesome', () => { let driver; before(async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 5', app: '/path/to/app.apk' }; driver = await new Builder().withCapabilities(capabilities).build(); }); after(async () => { await driver.quit(); }); it('should submit form successfully', async () => { const element = await driver.findElement(By.id('submit_button')); await element.click(); const result = await driver.findElement(By.id('result_message')); const text = await result.getText(); assert.strictEqual(text, 'Success'); }); });

Data-Driven Testing

1. Using JSON Data

javascript
const { Builder, By, until } = require('selenium-webdriver'); const testData = require('./test-data.json'); describe('Data-Driven Tests', () => { let driver; before(async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 5', app: '/path/to/app.apk' }; driver = await new Builder().withCapabilities(capabilities).build(); }); after(async () => { await driver.quit(); }); testData.forEach((data, index) => { it(`Test case ${index + 1}: ${data.description}`, async () => { const input = await driver.findElement(By.id('input_field')); await input.sendKeys(data.input); const button = await driver.findElement(By.id('submit_button')); await button.click(); const result = await driver.findElement(By.id('result_message')); const text = await result.getText(); assert.strictEqual(text, data.expected); }); }); });

2. Using Excel Data

javascript
const { Builder, By, until } = require('selenium-webdriver'); const xlsx = require('xlsx'); describe('Data-Driven Tests with Excel', () => { let driver; let testData; before(async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 5', app: '/path/to/app.apk' }; driver = await new Builder().withCapabilities(capabilities).build(); // Read Excel data const workbook = xlsx.readFile('./test-data.xlsx'); const sheet = workbook.Sheets['Sheet1']; testData = xlsx.utils.sheet_to_json(sheet); }); after(async () => { await driver.quit(); }); testData.forEach((data, index) => { it(`Test case ${index + 1}: ${data.description}`, async () => { const input = await driver.findElement(By.id('input_field')); await input.sendKeys(data.input); const button = await driver.findElement(By.id('submit_button')); await button.click(); const result = await driver.findElement(By.id('result_message')); const text = await result.getText(); assert.strictEqual(text, data.expected); }); }); });

Parallel Testing

1. Using Mocha Parallel Testing

javascript
const { Builder, By, until } = require('selenium-webdriver'); describe('Parallel Tests', () => { it('Test 1', async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 5', app: '/path/to/app.apk' }; const driver = await new Builder().withCapabilities(capabilities).build(); try { const element = await driver.findElement(By.id('submit_button')); await element.click(); } finally { await driver.quit(); } }); it('Test 2', async () => { const capabilities = { platformName: 'Android', deviceName: 'Pixel 6', app: '/path/to/app.apk' }; const driver = await new Builder().withCapabilities(capabilities).build(); try { const element = await driver.findElement(By.id('submit_button')); await element.click(); } finally { await driver.quit(); } }); });

2. Using TestNG Parallel Testing

java
import org.testng.annotations.*; import org.openqa.selenium.*; import org.openqa.selenium.remote.DesiredCapabilities; import io.appium.java_client.AppiumDriver; import io.appium.java_client.MobileElement; @Test(threadPoolSize = 3, invocationCount = 3) public class ParallelAppiumTests { @Test(dataProvider = "devices") public void testOnDevice(String deviceName) throws Exception { DesiredCapabilities capabilities = new DesiredCapabilities(); capabilities.setCapability("platformName", "Android"); capabilities.setCapability("deviceName", deviceName); capabilities.setCapability("app", "/path/to/app.apk"); AppiumDriver<MobileElement> driver = new AppiumDriver<>( new URL("http://localhost:4723/wd/hub"), capabilities ); try { MobileElement element = driver.findElement(By.id("submit_button")); element.click(); } finally { driver.quit(); } } @DataProvider(name = "devices") public Object[][] getDevices() { return new Object[][] { {"Pixel 5"}, {"Pixel 6"}, {"Pixel 7"} }; } }

Best Practices

  1. Choose the Right Testing Framework:

    • Choose based on team tech stack
    • Consider framework ecosystem
    • Evaluate learning cost
  2. Configure Continuous Integration:

    • Automate test execution
    • Generate test reports
    • Provide timely test feedback
  3. Implement Parallel Testing:

    • Improve test efficiency
    • Reduce test time
    • Fully utilize resources
  4. Use Data-Driven Testing:

    • Increase test coverage
    • Simplify test maintenance
    • Support multi-scenario testing
  5. Generate Detailed Reports:

    • Record test results
    • Analyze test trends
    • Improve test quality

Appium's test framework integration provides testers with flexible testing solutions. Through reasonable configuration and optimization, you can build an efficient and stable automation testing system.

标签:Appium