Создайте среду автоматизированного тестирования интерфейса jest+gitlab-ci.

внешний интерфейс тестовое задание
Создайте среду автоматизированного тестирования интерфейса jest+gitlab-ci.

Используйте jest + gitlab-ci для создания среды автоматизированного тестирования пользовательского интерфейса.

предисловие

Ниже приведен пример создания репозитория на github.Самое хлопотное в области тестирования — это фронтенд-тестирование пользовательского интерфейса.
гитлаб адрес:git lab.com/Yunqiangwu/…

Предпосылки

  • Иметь учетную запись gitlab (также внутри компании)
  • gitlab был настроен с помощью CI Runner (конкретный метод Baidu)

Эффект реализации функции

  • После изменения тестового случая нажатие запускает автоматический тест.
  • Создание отчета о тестировании после завершения теста
  • Отчеты о тестировании размещаются на страницах git.
  • Отправить уведомление по электронной почте о результатах теста и ссылку для просмотра отчета

Давайте посмотрим на мой эффект в реальном проекте Ниже приведено электронное письмо, которое я получил после завершения автоматизированного теста:

адрес предварительного просмотра
Отчет о тестировании автоматизации
Отчет о тестовом покрытии

Создать проект

mkdir devops-test
cd devops-test
npm init # 初始化 `node` 项目 
# 这里会要你输入信息,节约时间,一路回车
# 下面的操作我用的是cnpm 
cnpm i jest jest-report nightmare --save
cnpm i babel-jest babel-plugin-import babel-plugin-transform-class-properties babel-plugin-transform-decorators-legacy babel-plugin-transform-runtime 
 babel-preset-env --save-dev
#

Основные сведения о библиотеке зависимостей:

  • фреймворк для шутливого тестирования
  • кошмарная среда выполнения браузера
  • jest-report Производственная библиотека тестовых отчетов

Настройте среду шутки

  1. существуетpackage.jsonизscriptsСредний вызов подобен тестовой команде

    {
          "name": "devops-test",
          "version": "1.0.0",
          "description": "",
          "main": "index.js",
          "scripts": {
            "test": "jest e2e.js"
          },
          "author": "",
    
          // ...
      
     }
    
  2. Создайтеjasmineконфигурационный файл项目根目录/tests/jasmine.jsНастроить тайм-аут теста

    jasmine.DEFAULT_TIMEOUT_INTERVAL = 12000; // 只有这一行内容
    
  3. существуетpackage.jsonдобавить два поля вbabelа такжеjest, поэтому вы можете запустить код es6

    {
      "name": "devops-test",
      "version": "1.0.0",
      
      // ...
        
        "babel": {
        "presets": [
          "env"
        ],
        "plugins": [
          "transform-decorators-legacy",
          "transform-class-properties",
          "transform-es2015-destructuring"
        ]
      },
      "jest": {
        "testResultsProcessor": "jest-report",
        "setupTestFrameworkScriptFile": "<rootDir>/tests/jasmine.js",
        "testMatch": [
          "**/?(*.)(spec|test|e2e).js?(x)"
        ]
      },
          
       // ...
          
      }
    

Пишите тестовые случаи

тестовое заданиеgithubФункция входа<rootDir>/src/e2e/test-github-login.e2e.js

import Nightmare from 'nightmare';
import { helperBuilder } from 'jest-report';

describe('Login', () => {
    let page;
    beforeEach(() => {
        page = Nightmare({ show: true }).viewport(1024, 768);
        page.goto('https://github.com/login');
    });

    // afterEach(() => {
    //     if(page){
    //       page.halt();
    //       page = null;
    //     }
    // });

    it('should login with failure', async() => {
        const reportHelper = helperBuilder('Login', 'should login with failure');

        reportHelper.monitorPage(page);
        await page
            .type('#login_field', 'mockuser')
            .type('#password', 'wrong_password')
            .click('input[type="submit"]')
            .wait('#js-flash-container > div > div'); // should display error
        await page.screenshot(reportHelper.genPicturePath());
        const text = await page.wait('#js-flash-container > div > div')
            .evaluate(() => document.body.innerText)
            .end();
        await page.end();
        expect(text).toContain('Incorrect username or password');
    });

    it('should login successfully', async() => {
        const reportHelper = helperBuilder('Login', 'should login successfully');

        reportHelper.monitorPage(page);
        await page
            .type('#login_field', '正确用户名')
            .type('#password', '正确密码')
            .click('input[type="submit"]')
            .wait('#your_repos > div > div.boxed-group-action > a'); // should display error
        await page.screenshot(reportHelper.genPicturePath());
        const title = await page
            .evaluate(() => document.title)
            .end();
        await page.end();
        
        expect(title).toBe('GitHub');
    });


});

Запуск тестов для создания отчетов о тестировании

1. Run.npm testЗапустите тестовый темп

2. Создайте отчет о тестировании

生成的文件路径默认是 `<rootDir>/dist/test-report`

3. Эффект отчета об испытаниях

добавить проект в гитлаб

git init
git remote add origin https://gitlab.com/yunqiangwu/devops-test.git
git add .
git commit -m "Initial commit"
git push -u origin master

добавить к непрерывной интеграции

Автоматически развертывать отчеты о тестировании на веб-странице gitlab pages.

cnpm i --save-dev gh-pages

существуетpackage.jsonДобавить кscripts

"scripts": {
  "test": "jest e2e.js",
  "site": "gh-pages -d dist"
},

Настройка инструмента уведомлений по электронной почте
<rootDir>/tool/emailnotice.sh

#!/bin/bash
MAIL_FROM='supportman@yeah.net'
# [[ $MAIL_TO == "" ]] && export MAIL_TO=$1
MAIL_TO_ARR_ARG=$1
MAIL_SUBJECT=$2
shift 2
MAIL_CONTENT=$*
MAIL_CONTENT_FILE="/tmp/`/bin/date +%s`.txt"
MAIL_SMTP='smtp://smtp.yeah.net'
MAIL_USER='supportman@yeah.net'
MAIL_PASSWORD='wu950429'

OLD_IFS="$IFS"
#设置分隔符
IFS=","
MAIL_TO_ARR=($MAIL_TO_ARR_ARG)
IFS="$OLD_IFS"
split_1()
{

  MAIL_TO=$1
  echo "发送邮件到:"$1
  #  return 0;
  # create mail content file
  echo "From:${MAIL_FROM}
To:$MAIL_TO
Subject: $MAIL_SUBJECT

$MAIL_CONTENT
"> ${MAIL_CONTENT_FILE}

  # send mail
  curl -s --url "${MAIL_SMTP}" --mail-from "${MAIL_FROM}" --mail-rcpt ${MAIL_TO} --upload-file ${MAIL_CONTENT_FILE} --user "${MAIL_USER}:${MAIL_PASSWORD}"

}

for s in ${MAIL_TO_ARR[@]}
do
split_1 "$s"
done

rm -rf ${MAIL_CONTENT_FILE}

конфигурационный файл gitlab-ci.yml.gitlab-ci.yml


image: jonneywu/node-xvfb-cnpm

cache:
  key: "$CI_REPOSITORY_URL"
  paths:
    - node_modules
    - dist

stages:
 - test
 - email


test:
   script:
     - if [ ! -d node_modules ]; then cnpm i; fi
     - if [ ! -d node_modules/nightmare ]; then cnpm i nightmare; fi
     - export DISPLAY=':99.0'
     - Xvfb :99 -screen 0 1024x768x24 > /dev/null 2>&1 &
     - npm run test && echo test FAIL
     - kill -9 `ps -ef | grep Xvfb| grep -v grep|awk '{print $2}'`
     - npm run site
   stage: test
   only:
     - master
   artifacts:
     paths:
       - dist

email:
  script:
    - echo email
    - if [[ ! -n $MAIL_TO ]]; then export MAIL_TO=842269153@qq.com,yunqiang.wu@hand-china.com ; fi
    - export root_url=http://`cat CNAME`
    - export test_passed_rate=$(printf "%.2f" `cat dist/test-report/testResultData.json | jq '100*.numPassedTests/.numTotalTests'`)%
    - bash ./tool/emailnotice.sh $MAIL_TO '前端自动化测试' `echo -e "  测试分支: ${CI_COMMIT_REF_NAME} \r\n 提交人:${GITLAB_USER_NAME} \r\n 测试通过率:${test_passed_rate} \r\n 触发来源:${CI_PIPELINE_SOURCE} \r\n 测试环境:mockApi环境 \r\n\r\n预览地址: ${root_url}/index.html \r\n 自动化测试报告:${root_url}/test-report/reporter.html \r\n 测试覆盖率报告: ${root_url}/coverage/lcov-report/index.html \r\n"`
  stage: email
  only:
    - master
  artifacts:
    paths:
      - dist

Меры предосторожности

  • Реагировать на разработку, если вы используетеcss modulesКогда технология будет разработана, имя класса будет заменено, и тестовый фреймворк не пройдет.css selectorНайдите элемент Дом и управляйте им.id,data-customПользовательские атрибуты, такие как поле ввода имени пользователя, кнопка входа,
  • Автоматический тест, который я представляю здесь, предназначен только для проверки нормального функционального взаимодействия системы.Если необходимо полагаться на автоматическое тестирование, чтобы определить, соответствует ли сравнение стиля интерфейса пользовательского интерфейса требованиям, оно все еще может полагаться на тестирование человеком, но Цель теста - убедиться, что система работает нормально Невозможно использовать ОШИБКУ.

Ссылаться на