애플 릿 자동화 테스트 의 예제 코드
최근 에 팀 은 애플 릿 자동화 테스트 도 구 를 만 들 계획 이다.할 수 있 는 업무 자 들 이 애플 릿 을 한 번 조작 한 후에 이전의 작업 경 로 를 자동 으로 복원 하고 작업 과정 에서 발생 하 는 이상 을 포착 하여 이번 발표 가 애플 릿 의 기본 기능 에 영향 을 미 칠 것 이 라 고 판단 할 계획 이다.
상술 한 설명 은 간단 해 보이 지만 중간 에 어 려 운 점 이 있다.첫 번 째 어 려 운 점 은 업무 인원 이 작은 프로그램 을 조작 할 때 조작 경 로 를 기록 하 는 것 이다.두 번 째 어 려 운 점 은 기 록 된 조작 경 로 를 어떻게 복원 하 는 지 하 는 것 이다.
자동화 SDK
이 문 제 를 어떻게 복원 하 는 지,물론 공식 적 으로 제공 하 는 SDK:
miniprogram-automator
를 우선 선택 하 십시오.애플 릿 자동화SDK는 개발 자 에 게 외부 스 크 립 트 를 통 해 애플 릿 을 조작 하 는 방안 을 제공 하여 애플 릿 자동화 테스트 의 목적 을 실현 했다.이 SDK 를 통 해 다음 과 같은 일 을 할 수 있 습 니 다.
// sdk
const automator = require('miniprogram-automator')
//
automator.launch({
// cli
// Windows cli.bat
// MacOS cli
cliPath: 'path/to/cli',
// ,
projectPath: 'path/to/project',
}).then(async miniProgram => { // miniProgram IDE
// index
const page = await miniProgram.reLaunch('/page/index/index')
// 500 ms
await page.waitFor(500)
//
const element = await page.$('.main-btn')
//
await element.tap()
// IDE
await miniProgram.close()
})
SDK 를 사용 하기 전에 개발 자 도구 의 서비스 포트 를 켜 야 합 니 다.그렇지 않 으 면 시작 에 실 패 했 습 니 다.사용자 행동 캡 처
조작 경 로 를 복원 하 는 방법 이 생 겼 으 니 다음은 조작 경 로 를 기록 하 는 어 려 운 문 제 를 해결 해 야 한다.
작은 프로그램 에 서 는 웹 에서 이벤트 거품 을 일 으 키 는 방식 으로 window 에서 모든 사건 을 포착 할 수 없습니다.예 를 들 어 작은 프로그램 에 서 는 페이지 와 구성 요소 가
Page
,Component
방법 으로 포장 되 어야 하기 때문에 우 리 는 이 두 가지 방법 을 바 꾸 어 전송 을 차단 하 는 방법 을 바 꾸 고 첫 번 째 매개 변수 가event
대상 인지 판단 할 수 있 습 니 다.모든 사건 을 포착 하 겠 습 니 다.
//
const originPage = Page
const originComponent = Component
// Page
Page = (params) => {
const names = Object.keys(params)
for (const name of names) {
//
if (typeof obj[name] === 'function') {
params[name] = hookMethod(name, params[name], false)
}
}
originPage(params)
}
// Component
Component = (params) => {
if (params.methods) {
const { methods } = params
const names = Object.keys(methods)
for (const name of names) {
//
if (typeof methods[name] === 'function') {
methods[name] = hookMethod(name, methods[name], true)
}
}
}
originComponent(params)
}
const hookMethod = (name, method, isComponent) => {
return function(...args) {
const [evt] = args //
// event
if (evt && evt.target && evt.type) {
//
}
return method.apply(this, args)
}
}
이 코드 는 모든 이벤트 방법 을 대리 할 뿐 사용자 의 행 위 를 복원 하 는 데 사용 할 수 없습니다.사용자 의 행 위 를 복원 하려 면 이 이벤트 유형 이 필요 한 지 알 아야 합 니 다.예 를 들 어 클릭,길 게 누 르 기,입력 등 입 니 다.
const evtTypes = [
'tap', //
'input', //
'confirm', //
'longpress' //
]
const hookMethod = (name, method) => {
return function(...args) {
const [evt] = args //
// event
if (
evt && evt.target && evt.type &&
evtTypes.includes(evt.type) //
) {
//
}
return method.apply(this, args)
}
}
이벤트 형식 을 확인 한 후에 클릭 한 요소 가 도대체 어디 인지 명확 하 게 해 야 합 니 다.그러나 작은 프로그램 에서 구 덩이 를 비교 하 는 곳 은 이벤트 대상 의 target 속성 에 요소 의 유형 은 없 지만 요소 의 dataset 를 얻 을 수 있 습 니 다.요 소 를 정확하게 얻 기 위해 서 는 구축 에 절 차 를 추가 하고 wxml 파일 을 수정 하여 요소 의
class
속성 을data-className
로 복사 해 야 합 니 다.
<!-- -->
<view class="close-btn"></view>
<view class="{{mainClassName}}"></view>
<!-- -->
<view class="close-btn" data-className="close-btn"></view>
<view class="{{mainClassName}}" data-className="{{mainClassName}}"></view>
그러나 클 라 스 를 가 져 오 면 또 다른 구덩이 가 있 습 니 다.애플 릿 의 자동화 테스트 도 구 는 페이지 에 있 는 사용자 정의 구성 요소 의 요 소 를 직접 가 져 올 수 없습니다.사용자 정의 구성 요 소 를 먼저 가 져 와 야 합 니 다.
<!-- Page -->
<toast text="loading" show="{{showToast}}" />
<!-- Component -->
<view class="toast" wx:if="{{show}}">
<text class="toast-text">{{text}}</text>
<view class="toast-close" />
</view>
// .toast-close null
const element = await page.$('.toast-close')
element.tap() // Error!
// tagName
// className
const element = await page.$('toast .toast-close')
element.tap()
그래서 우 리 는 빌 드 작업 을 할 때 요소 에 tagName 을 삽입 해 야 합 니 다.
<!-- -->
<view class="close-btn" />
<toast text="loading" show="{{showToast}}" />
<!-- -->
<view class="close-btn" data-className="close-btn" data-tagName="view" />
<toast text="loading" show="{{showToast}}" data-tagName="toast" />
이제 우 리 는 사용자 의 행동 을 계속 즐겁게 기록 할 수 있다.
//
const actions = [];
//
const addAction = (type, query, value = '') => {
actions.push({
time: Date.now(),
type,
query,
value
})
}
//
const hookMethod = (name, method, isComponent) => {
return function(...args) {
const [evt] = args //
// event
if (
evt && evt.target && evt.type &&
evtTypes.includes(evt.type) //
) {
const { type, target, detail } = evt
const { id, dataset = {} } = target
const { className = '' } = dataset
const { value = '' } = detail // input ,
//
let query = ''
if (isComponent) {
// , tagName
query = `${this.dataset.tagName} `
}
if (id) {
// id , id
query += id
} else {
// id , className
query += className
}
addAction(type, query, value)
}
return method.apply(this, args)
}
}
사용자 의 모든 클릭,입력,리 턴 과 관련 된 작업 을 기 록 했 지만 스크롤 스크린 작업 은 기록 되 지 않 았 습 니 다.페이지 의 onPage Scroll 을 직접 감청 할 수 있 습 니 다.
//
const actions = [];
//
const addAction = (type, query, value = '') => {
if (type === 'scroll' || type === 'input') {
// , value
const last = this.actions[this.actions.length - 1]
if (last && last.type === type) {
last.value = value
last.time = Date.now()
return
}
}
actions.push({
time: Date.now(),
type,
query,
value
})
}
Page = (params) => {
const names = Object.keys(params)
for (const name of names) {
//
if (typeof obj[name] === 'function') {
params[name] = hookMethod(name, params[name], false)
}
}
const { onPageScroll } = params
//
params.onPageScroll = function (...args) {
const [evt] = args
const { scrollTop } = evt
addAction('scroll', '', scrollTop)
onPageScroll.apply(this, args)
}
originPage(params)
}
여기 에는 스크롤 작업 기록 이 있 을 때 마지막 작업 도 스크롤 작업 인지 판단 할 수 있 습 니 다.같은 작업 이 라면 스크롤 거 리 를 수정 하면 됩 니 다.두 번 스크롤 하면 한 걸음 에 도착 할 수 있다 고 생각 합 니 다.마찬가지 로 입력 이벤트 도 입력 한 값 이 한 걸음 에 도착 할 수 있 습 니 다.사용자 행동 복원
사용자 작업 이 끝 난 후 콘 솔 에서 사용자 행동 의 제 이 슨 텍스트 를 출력 하고 제 이 슨 텍스트 를 복사 하면 자동화 도 구 를 통 해 실행 할 수 있 습 니 다.
// sdk
const automator = require('miniprogram-automator')
//
const actions = [
{ type: 'tap', query: 'goods .title', value: '', time: 1596965650000 },
{ type: 'scroll', query: '', value: 560, time: 1596965710680 },
{ type: 'tap', query: 'gotoTop', value: '', time: 1596965770000 }
]
//
automator.launch({
projectPath: 'path/to/project',
}).then(async miniProgram => {
let page = await miniProgram.reLaunch('/page/index/index')
let prevTime
for (const action of actions) {
const { type, query, value, time } = action
if (prevTime) {
//
await page.waitFor(time - prevTime)
}
//
prevTime = time
//
page = await miniProgram.currentPage()
switch (type) {
case 'tap':
const element = await page.$(query)
await element.tap()
break;
case 'input':
const element = await page.$(query)
await element.input(value)
break;
case 'confirm':
const element = await page.$(query)
await element.trigger('confirm', { value });
break;
case 'scroll':
await miniProgram.pageScrollTo(value)
break;
}
// , 5s, ,
await page.waitFor(5000)
}
// IDE
await miniProgram.close()
})
여 기 는 사용자 의 조작 행 위 를 간단하게 복원 하 는 것 일 뿐 실제 실행 과정 에서 네트워크 요청 과 localstorage 의 mock 도 포함 되 어 더 이상 설명 하지 않 습 니 다.또한,우 리 는 jest 도구 에 접속 하여,더욱 편리 하 게 사례 를 작성 할 수 있 습 니 다.총결산
어 려 울 것 같은 요 구 는 열심히 발굴 하면 그 에 맞 는 해결책 을 찾 을 수 있다.또한 위 챗 애플 릿 의 자동화 도 구 는 정말 많은 구덩이 가 있 습 니 다.문제 가 발생 하면 먼저 애플 릿 커 뮤 니 티 에 가서 찾 아 볼 수 있 습 니 다.대부분 구 덩이 는 앞 사람 이 밟 았 고 일시 적 으로 해결 할 수 없 는 문 제 는 다른 방법 으로 피 할 수 밖 에 없습니다.마지막 으로 천하 에 bug 가 없 기 를 기원 합 니 다.
애플 릿 자동화 테스트 에 관 한 예제 코드 에 관 한 이 글 은 여기까지 소개 되 었 습 니 다.더 많은 애플 릿 자동화 테스트 내용 은 우리 의 이전 글 을 검색 하거나 아래 의 관련 글 을 계속 조회 하 시기 바 랍 니 다.앞으로 많은 응원 바 랍 니 다!
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
애플 릿 이미지 새로 고침, nginx 재 작성 url 제거 인자이전에 nginx 로 이미지 서버 를 만 들 었 는데 전단 에 작은 프로그램 을 사 용 했 습 니 다. 작은 프로그램 이 출시 된 후에 그림 이 새로 고침 되 지 않 는 것 을 발 견 했 습 니 다. 조사 한 결과 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.