使用Appium自动测试你的React Native

发表于:2023-2-01 09:06

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:一天两升水    来源:稀土掘金

  Appium是一款开源测试工具,可以用来测试安卓/iOS/Windows端的原生应用和Web混合应用。
  工作原理
  Appium有一个客户端-服务器架构。Appium客户端向Appium服务器(一个Node.js HTTP服务器)发送请求,反过来,Appium服务器向执行动作的设备发送请求。然后,服务器将结果返回给客户端,让你知道测试的状态。
  功能
  ·跨平台
  · 多开发语言支持
  · 不需要重新编译应用程序
  · 不需要重复找轮子,可共用API
  · 市场占有率TOP1
  优点
  1. 方便的切换测试原生应用或App内嵌的web页面,对Hybrid App友好。
  2. 使用各个平台自身提供的测试框架,因此无需引入第三方代码或重新打包应用。
  3. 开源,维护频率很高,社区也有相对较高的活跃度。
  4. 支持通过自定义插件寻找元素。
  缺点
  1. 不支持单元测试、跨应用测试。
  2. 测试效率相对较低。
  使用
  默认您已经安装node以及对应的Android或IOS等相关环境
  使用appium有两种方式:
  方式1:npm;
  方式2:下载Appium Desktop,这是一种基于图形的、基于桌面的方式来启动 Appium 服务器。
  这里主要介绍npm的使用方式
  step 1: 安装appium
  npm install -g appium 
  step 2: 安装webdriverio
  npm install --save webdriverio @wdio/cli
  webdriverio是什么?
  基于Node.js的下一代浏览器和移动自动化测试框架
  生成 Web 驱动程序配置文件以在测试时应用配置。
  step 3: 配置webdriverio
  执行npx wdio config:
  生成的文件目录如下:
  及wdio.conf.js配置文件复制并修改有注释的字段到你的wdio.config.js文件。
  exports.config = {
    port: 4723,
    services: [['appium', {command: 'appium'}]],
    runner: 'local',
    specs: ['./test/specs/**/*.js'], // 测试目录
    maxInstances: 1,
    capabilities: [
      {
        maxInstances: 1,
        browserName: '',
        appiumVersion: '1.22.3', // appium -v 获取
        platformName: 'Android',
        platformVersion: '9', // 安卓版本
        deviceName: 'Nexus_S_API_28', // 设备名称 执行adb -s emulator-5554 emu avd name 获取
        app: './android/app/build/outputs/apk/debug/app-debug.apk', // apk目录, 没有的话先在Android studio build一个
        automationName: 'UiAutomator2',
      },
    ],
    logLevel: 'trace',
    bail: 0,
    waitforTimeout: 10000,
    connectionRetryTimeout: 90000,
    connectionRetryCount: 3,
    framework: 'mocha',
    reporters: ['dot'],
    mochaOpts: {
      ui: 'bdd',
      timeout: 60000,
    },
  };
  step 4: 创建一个测试用例
  修改test/specs/example.e2e.js文件。
  describe('Simple App testing', () => {
    beforeEach(async () => {
      const app = await $('~app-root');
      await app.waitForDisplayed(10000, false);
    });
    it('Login test: valid case', async () => {
      const username = await $('~username');
      await username.setValue('codemagic');
      const password = await $('~password');
      await password.setValue('nevercode');
      const loginBtn = await $('~login');
      await loginBtn.click();
      await $('~loginstatus').waitForDisplayed(11000);
      const status = await $('~loginstatus').getText();
      expect(status).toHaveValueContaining('登录成功');
    });
    it('Login test: invalid case', async () => {
      await $('~username').setValue('nevercode');
      await $('~password').setValue('codemagic');
      await $('~login').click();
      await $('~loginstatus').waitForDisplayed(11000);
      const status = await $('~loginstatus').getText();
      expect(status).toHaveValueContaining('未登录'); // 断言https://webdriver.io/docs/api/expect-webdriverio
    });
  });
  step 5: 创建一个app页面
  如图:
  修改你的App.js:
  import React, {Component} from 'react';
  import {
    TouchableHighlight,
    StyleSheet,
    Text,
    TextInput,
    View,
  } from 'react-native';
  export default class App extends Component {
    constructor() {
      super();
      this.state = {
        username: '',
        password: '',
        isLogined: false,
      };
    }
    inputChangeHandler = (value, name) => {
      this.setState({
        [name]: value,
      });
    };
    login = () => {
      if (
        this.state.username === 'codemagic' &&
        this.state.password === 'nevercode'
      ) {
        this.setState({isLogined: true});
      } else {
        this.setState({isLogined: false});
      }
    };
    render() {
      return (
        <View
          style={LOCAL_STYLES.wrapper}
          testID="app-root"
          accessibilityLabel="app-root">
          <Text style={{fontSize: 22, marginBottom: 20}}>登录页面</Text>
          <View style={LOCAL_STYLES.inputContainer}>
            <TextInput
              name="username"
              accessibilityLabel="username"
              style={LOCAL_STYLES.input}
              onChangeText={text => this.inputChangeHandler(text, 'username')}
            />
          </View>
          <View style={LOCAL_STYLES.inputContainer}>
            <TextInput
              name="password"
              accessibilityLabel="password"
              secureTextEntry={true}
              style={LOCAL_STYLES.input}
              onChangeText={text => this.inputChangeHandler(text, 'password')}
            />
          </View>
          <Text accessibilityLabel="loginstatus">
            {this.state.isLogined ? '登录成功' : '未登录'}
          </Text>
          <TouchableHighlight
            style={LOCAL_STYLES.buttonContainer}
            accessibilityLabel="login"
            onPress={this.login}>
            <Text style={{color: 'white'}}>Login</Text>
          </TouchableHighlight>
        </View>
      );
    }
  }
  const LOCAL_STYLES = StyleSheet.create({
    wrapper: {
      flex: 1,
      alignItems: 'center',
      justifyContent: 'center',
    },
    inputContainer: {
      borderBottomColor: '#AFAFAF',
      backgroundColor: '#FFFFFF',
      borderRadius: 10,
      borderBottomWidth: 1,
      marginBottom: 16,
      flexDirection: 'row',
      alignItems: 'center',
      width: '80%',
      borderColor: 'blue',
      borderWidth: 1,
    },
    buttonContainer: {
      height: 45,
      width: 250,
      flexDirection: 'row',
      justifyContent: 'center',
      alignItems: 'center',
      marginBottom: 20,
      borderRadius: 20,
      backgroundColor: '#00b5ec',
    },
  });
  step 6:  编译你的应用到模拟器
  yarn android
  yarn start
  step 7:  执行测试用例
  npx wdio ./wdio.conf.js
  执行通过后会有passed的打印:
  Spec Files:      1 passed, 1 total (100% completed) in 00:00:32
  至此,测试结束!
  Q&A
  如何来标识RN组件?
  对于 Android,添加accessibilityLabel属性;
  对于 iOS,添加testID属性。
   <View style={LOCAL_STYLES.inputContainer}>
        <TextInput name="password" accessibilityLabel="password" testID='password' secureTextEntry={true} style={LOCAL_STYLES.input} onChangeText={(text) => this.inputChangeHandler(text, "password")} />
   </View>
  本文内容不用于商业目的,如涉及知识产权问题,请权利人联系51Testing小编(021-64471599-8017),我们将立即处理
《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号