提交 d3ca3e75 编写于 作者: DCloud_JSON's avatar DCloud_JSON

新增的state状态的自动化测试例

上级 b496f0a3
......@@ -6,6 +6,6 @@ module.exports = {
watchPathIgnorePatterns: ['/node_modules/', '/dist/', '/.git/'],
moduleFileExtensions: ['js', 'json'],
rootDir: __dirname,
testMatch: ["<rootDir>/pages/**/*test.[jt]s?(x)"],
testMatch: ["<rootDir>/pages/state/**/*.test.js"],
testPathIgnorePatterns: ['/node_modules/']
}
{
"name" : "hello-uvue",
"appid" : "",
"appid" : "__UNI__CD1E05C",
"description" : "",
"versionName" : "1.0.0",
"versionCode" : "100",
......
{
"pages": [{
"path": "pages/index",
"style": {
"navigationBarTitleText": "hello uvue"
}
},
{
"path": "pages/v-bind/v-bind",
"style": {
"navigationBarTitleText": "v-bind"
}
},
{
"path": "pages/v-for/v-for",
"style": {
"navigationBarTitleText": "v-for"
}
},
{
"path": "pages/v-if/v-if",
"style": {
"navigationBarTitleText": "v-if"
}
},
{
"path": "pages/v-model/v-model",
"style": {
"navigationBarTitleText": "v-model"
}
},
{
"path": "pages/v-on/v-on",
"style": {
"navigationBarTitleText": "v-on"
}
},
{
"path": "pages/v-once/v-once",
"style": {
"navigationBarTitleText": "v-once"
}
},
{
"path": "pages/v-show/v-show",
"style": {
"navigationBarTitleText": "v-show"
}
},
{
"path": "pages/v-slot/v-slot",
"style": {
"navigationBarTitleText": "v-slot"
}
}
],
"globalStyle": {
"pageOrientation": "portrait",
"navigationBarTitleText": "Hello UVUE",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#F8F8F8",
"backgroundColorTop": "#F4F5F6",
"backgroundColorBottom": "#F4F5F6",
"h5": {
"maxWidth": 1190,
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#F1F1F1"
}
},
"uniIdRouter": {},
"condition": { //模式配置,仅开发期间生效
"current": 0, //当前激活的模式(list 的索引项)
"list": [{
"name": "", //模式名称
"path": "", //启动页面,必选
"query": "" //启动参数,在页面的onLoad函数里面得到
}]
}
{
"pages": [{
"path": "pages/index",
"style": {
"navigationBarTitleText": "hello uvue"
}
}, {
"path": "pages/state/data/data",
"style": {
"navigationBarTitleText": "data",
"enablePullDownRefresh": false
}
},
{
"path": "pages/v-bind/v-bind",
"style": {
"navigationBarTitleText": "v-bind"
}
},
{
"path": "pages/v-for/v-for",
"style": {
"navigationBarTitleText": "v-for"
}
},
{
"path": "pages/v-if/v-if",
"style": {
"navigationBarTitleText": "v-if"
}
},
{
"path": "pages/v-model/v-model",
"style": {
"navigationBarTitleText": "v-model"
}
},
{
"path": "pages/v-on/v-on",
"style": {
"navigationBarTitleText": "v-on"
}
},
{
"path": "pages/v-once/v-once",
"style": {
"navigationBarTitleText": "v-once"
}
},
{
"path": "pages/v-show/v-show",
"style": {
"navigationBarTitleText": "v-show"
}
},
{
"path": "pages/v-slot/v-slot",
"style": {
"navigationBarTitleText": "v-slot"
}
},
{
"path": "pages/state/methods/methods",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/state/props/props",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/state/computed/computed",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}, {
"path": "pages/state/watch/watch",
"style": {
"navigationBarTitleText": "",
"enablePullDownRefresh": false
}
}
],
"globalStyle": {
"pageOrientation": "portrait",
"navigationBarTitleText": "Hello UVUE",
"navigationBarTextStyle": "white",
"navigationBarBackgroundColor": "#007AFF",
"backgroundColor": "#F8F8F8",
"backgroundColorTop": "#F4F5F6",
"backgroundColorBottom": "#F4F5F6",
"h5": {
"maxWidth": 1190,
"navigationBarTextStyle": "black",
"navigationBarBackgroundColor": "#F1F1F1"
}
},
"uniIdRouter": {},
"condition": { //模式配置,仅开发期间生效
// "current": 0, //当前激活的模式(list 的索引项)
// "list": [{
// "name": "state-data", //模式名称
// "path": "/pages/state/data/data", //启动页面,必选
// "query": "" //启动参数,在页面的onLoad函数里面得到
// }]
}
}
\ No newline at end of file
<template>
<view class="uni-container">
<view class="uni-panel" v-for="(item, index) in list" :key="item.id">
<view class="uni-panel-h" @click="triggerCollapse(item, index)">
<text class="uni-panel-text">{{item.name}}</text>
<!-- <text class="uni-panel-icon uni-icon" :class="item.open ? 'uni-panel-icon-on' : ''">{{item.open ? '&#xe581;' : '&#xe470;'}}</text> -->
</view>
<view class="uni-panel-c" v-if="item.open">
<view class="uni-navigate-item" v-for="(page,key) in item.pages" :key="key" @click="goDetailPage(page)">
<text class="uni-navigate-text">{{page}}</text>
<!-- <text class="uni-navigate-icon uni-icon">&#xe470;</text> -->
</view>
</view>
</view>
</view>
</template>
<script lang="ts">
const STORAGE_KEY_PREFIX = 'INDEX-STATUS'
let storageData : Array<string> = []
type ListItem = {
id : string,
name : string,
open : boolean,
pages : string[]
}
export default {
data() {
return {
list: [
{
id: 'lifecycle',
name: '生命周期',
open: false,
pages: [
'beforeCreate',
'created',
'beforeMount',
'mounted',
// 'beforeUpdate',
// 'updated',
'beforeUnmount',
'unmounted',
'activated',
'deactivated',
]
},
{
id: 'directives',
name: '指令',
open: false,
pages: [
'v-for',
'v-if',
'v-show',
'v-on',
'v-bind',
'v-model',
'v-slot',
// 'v-pre',
'v-once',
// 'v-memo',
// 'v-cloak'
]
},
{
id: 'state',
name: '状态',
open: false,
pages: [
'data',
'props',
'computed',
'methods',
'watch'
]
},
{
id: 'rendering',
name: '渲染选项',
open: false,
pages: ['template', 'render', 'slots']
},
{
id: 'component-instance',
name: '组件实例',
open: false,
pages: [
'$data',
'$props',
'$el',
'$options',
'$parent',
'$root',
'$slots',
'$refs',
'$attrs',
'$watch()',
'$emit()',
'$forceUpdate()',
'$nextTick()'
]
},
{
id: 'composition',
name: '组合选项',
open: false,
pages: [
'provide',
'inject',
'mixins',
'extends'
]
}
] as ListItem[]
}
},
onLoad() {
// uni.getStorage({
// key: STORAGE_KEY_PREFIX,
// success: function (res) {
// storageData = JSON.parse(res.data as string) as Array<string>
// console.log(storageData)
// for (let i = 0; i < this.list.length; ++i) {
// const item = this.list[i]
// if (storageData.includes(item.id)) {
// item.open = true
// }
// }
// }
// })
},
methods: {
triggerCollapse(_ : ListItem, index : number) {
this.list[index].open = !this.list[index].open
// const id = item.id
// const value = this.list[index].open
// if (value) {
// storageData.push(id)
// } else {
// const index2: number = storageData.indexOf(id)
// if (index2 > -1) {
// storageData.splice(index2, 1)
// }
// }
// uni.setStorage({
// key: STORAGE_KEY_PREFIX,
// data: storageData
// })
},
goDetailPage(e : string) {
uni.navigateTo({
url: `/pages/${e}/${e}`
})
}
}
}
</script>
<style>
.arrow {
width: 8px;
height: 8px;
border-top: 2px solid #ccc;
border-left: 2px solid #ccc;
}
.arrow-right {
transform: rotate(135deg);
}
.arrow-up {
transform: rotate(45deg);
}
.arrow-down {
transform: rotate(-135deg);
}
<template>
<view class="uni-container">
<view class="uni-panel" v-for="(item, index) in list" :key="item.id">
<view class="uni-panel-h" @click="triggerCollapse(item, index)">
<text class="uni-panel-text">{{item.name}}</text>
<!-- <text class="uni-panel-icon uni-icon" :class="item.open ? 'uni-panel-icon-on' : ''">{{item.open ? '&#xe581;' : '&#xe470;'}}</text> -->
</view>
<view class="uni-panel-c" v-if="item.open">
<view class="uni-navigate-item" v-for="(page,key) in item.pages" :key="key" @click="goDetailPage(page,item.id)">
<text class="uni-navigate-text">{{page}}</text>
<!-- <text class="uni-navigate-icon uni-icon">&#xe470;</text> -->
</view>
</view>
</view>
</view>
</template>
<script lang="ts">
const STORAGE_KEY_PREFIX = 'INDEX-STATUS'
let storageData : Array<string> = []
type ListItem = {
id : string,
name : string,
open : boolean,
pages : string[]
}
export default {
data() {
return {
list: [
{
id: 'lifecycle',
name: '生命周期',
open: false,
pages: [
'beforeCreate',
'created',
'beforeMount',
'mounted',
// 'beforeUpdate',
// 'updated',
'beforeUnmount',
'unmounted',
'activated',
'deactivated',
]
},
{
id: 'directives',
name: '指令',
open: false,
pages: [
'v-for',
'v-if',
'v-show',
'v-on',
'v-bind',
'v-model',
'v-slot',
// 'v-pre',
'v-once',
// 'v-memo',
// 'v-cloak'
]
},
{
id: 'state',
name: '状态',
open: false,
pages: [
'data',
'props',
'computed',
'methods',
'watch'
]
},
{
id: 'rendering',
name: '渲染选项',
open: false,
pages: ['template', 'render', 'slots']
},
{
id: 'component-instance',
name: '组件实例',
open: false,
pages: [
'$data',
'$props',
'$el',
'$options',
'$parent',
'$root',
'$slots',
'$refs',
'$attrs',
'$watch()',
'$emit()',
'$forceUpdate()',
'$nextTick()'
]
},
{
id: 'composition',
name: '组合选项',
open: false,
pages: [
'provide',
'inject',
'mixins',
'extends'
]
}
] as ListItem[]
}
},
onLoad() {
// uni.getStorage({
// key: STORAGE_KEY_PREFIX,
// success: function (res) {
// storageData = JSON.parse(res.data as string) as Array<string>
// console.log(storageData)
// for (let i = 0; i < this.list.length; ++i) {
// const item = this.list[i]
// if (storageData.includes(item.id)) {
// item.open = true
// }
// }
// }
// })
},
methods: {
triggerCollapse(_ : ListItem, index : number) {
this.list[index].open = !this.list[index].open
// const id = item.id
// const value = this.list[index].open
// if (value) {
// storageData.push(id)
// } else {
// const index2: number = storageData.indexOf(id)
// if (index2 > -1) {
// storageData.splice(index2, 1)
// }
// }
// uni.setStorage({
// key: STORAGE_KEY_PREFIX,
// data: storageData
// })
},
goDetailPage(e : string, id : string) {
console.log('goDetailPage', e, id);
if (id == 'state') {
uni.navigateTo({
url: `/pages/${id}/${e}/${e}`
})
} else {
uni.navigateTo({
url: `/pages/${e}/${e}`
})
}
}
}
}
</script>
<style>
.arrow {
width: 8px;
height: 8px;
border-top: 2px solid #ccc;
border-left: 2px solid #ccc;
}
.arrow-right {
transform: rotate(135deg);
}
.arrow-up {
transform: rotate(45deg);
}
.arrow-down {
transform: rotate(-135deg);
}
</style>
\ No newline at end of file
// uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
const PAGE_PATH = '/pages/state/computed/computed'
let page;
describe('/pages/state/computed/computed', () => {
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
page = await program.currentPage();
console.log('page', page);
// await page.waitFor(3000);
});
it('检查“计算属性”的数据是否渲染正确', async () => {
let num = 3
let computedNum = await getText('#computedNum')
console.log('computedNum',computedNum);
expect(parseInt(computedNum)).toEqual(num);
page.callMethod('addB')
num ++
computedNum = await getText('#computedNum')
expect(parseInt(computedNum)).toEqual(num);
});
});
async function getText(param){
return await (await page.$(param)).text();
}
\ No newline at end of file
<template>
<view class="content">
<text>变量a的值:{{a}}</text>
<text>变量b的值:{{b}}</text>
<view class="row">
<text>computed中返回a+b的值:</text>
<text id="computedNum">{{computedNum}}</text>
</view>
<button @click="addB" size="mini" type="primary">给变量b的值+1</button>
</view>
</template>
<script>
export default {
data() {
return {
a: 1,
b: 2
}
},
computed: {
computedNum(): number {
return this.a + this.b
}
},
methods: {
addB() {
this.b++
}
}
}
</script>
<style>
.content {
padding: 5px;
}
.row {
flex-direction: row;
}
</style>
\ No newline at end of file
// uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
const PAGE_PATH = '/pages/state/data/data'
let page;
describe('/pages/state/state', () => {
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
page = await program.currentPage();
console.log('page', page);
// await page.waitFor(3000);
});
const data = {
num: 2023,
str: '我是字符串',
obj: {
name: 'John',
age: 30
},
arr: [1, 2, 3, 4, 5, 6, 7]
}
it('检查“data”是否渲染正确', async () => {
const num = await getText('#num')
expect(parseInt(num)).toEqual(data.num);
const str = await getText('#str')
expect(str).toEqual(data.str);
const obj_name = await getText('#obj_name')
expect(obj_name).toEqual(data.obj.name);
const obj_age = await getText('#obj_age')
expect(parseInt(obj_age)).toEqual(data.obj.age);
const arr = await getText('#arr')
expect(JSON.parse(arr)).toEqual(data.arr);
for (var i = 0; i < data.arr.length; i++) {
let arr_item = await getText('#arr_'+i)
expect(parseInt(arr_item)).toEqual(data.arr[i]);
}
});
});
async function getText(param){
return await (await page.$(param)).text();
}
\ No newline at end of file
<template>
<view>
<view class="item">
<text class="type">数值型数据:</text>
<text class="value" id="num">{{num}}</text>
</view>
<view class="item">
<text class="type">字符串型数据:</text>
<text class="value" id="str">{{str}}</text>
</view>
<view class="item">
<text class="type">对象型数据:</text>
<!-- TODO object -->
<!-- <text v-for="(key,val) in obj">{{key}},{{val}}</text> -->
<view class="column">
<view class="row">
<text>对象中name的值:</text>
<text id="obj_name">{{obj.name}}</text>
</view>
<view class="row">
<text>对象中age的值:</text>
<text id="obj_age">{{obj.age}}</text>
</view>
</view>
</view>
<view class="item">
<text class="type">数组型数据:</text>
<text class="value row" id="arr">{{arr}}</text>
<text>通过for循环显示:</text>
<view class="row" v-for="(item,index) in arr" :key="index" style="padding-left: 10px;">
<text>第{{index}}项目的值:</text>
<text :id="'arr_'+index">{{item}}</text>
</view>
</view>
</view>
</template>
<script lang="ts">
type myObj = { name : string, age : number };
// 理论上支持但不支持的写法
// let obj:{ name : string, age : number } = { name: 'John', age: 30 }
export default {
data() : object {
return {
num: 2023 as number,
str: '我是字符串' as string,
obj: { name: 'John', age: 30 } as myObj,
arr: [1,2,3,4,5,6,7] as number[]
}
},
onLoad() {
console.log('获取所有 data 中的变量',this.$data);
console.log('获取data中的变量num',this.num);
console.log('获取data中的变量num',this.$data.get('num'));
}
}
</script>
<style>
.item{
padding: 5px;
flex-direction: row;
flex-wrap: wrap;
position: relative;
border-bottom: 0.1px solid #888;
}
.row{
width: 500rpx;
flex-direction: row;
}
.column{
flex-direction: column;
}
</style>
\ No newline at end of file
// uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
const PAGE_PATH = '/pages/state/methods/methods'
let page;
describe('/pages/state/methods/methods', () => {
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
page = await program.currentPage();
console.log('page', page);
// await page.waitFor(3000);
});
it('检查“通过方法返回的数据”是否正确(从视图中拿)', async () => {
page.callMethod('addNum')
page.callMethod('getMultiply100Num')
//显示在界面上的 num乘于100的数
let multiply100Num = await getText('#multiply100Num')
console.log('multiply100Num', multiply100Num);
let num = await getText('#num')
console.log('num', num);
console.log('multiply100Num', multiply100Num);
expect(num*100).toEqual(multiply100Num*1);
page.callMethod('addNum')
page.callMethod('getMultiply100Num')
//显示在界面上的 num乘于100的数
multiply100Num = await getText('#multiply100Num')
console.log('multiply100Num', multiply100Num);
num = await getText('#num')
console.log('num', num);
console.log('multiply100Num', multiply100Num);
expect(num*100).toEqual(multiply100Num*1);
});
});
async function getText(param) {
return await (await page.$(param)).text();
}
\ No newline at end of file
<template>
<view class="content">
<view class="row">
<text>数值型变量num的值:</text>
<text id="num">{{num}}</text>
</view>
<button @click="addNum">给变量num+1</button>
<view class="row">
<text>通过方法,获取乘于100之后的num的值:</text>
<text id="multiply100Num">{{getMultiply100Num()}}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
num:0,
arr:["第一项","第二项"]
}
},
methods: {
addNum(){
this.num ++
},
getMultiply100Num() : number{
return num * 100
}
}
}
</script>
<style>
.content {
padding: 5px;
}
.row {
flex-direction: row;
}
</style>
<template>
<view>
<view class="item">
<text class="title">字符串型数据:</text>
<text class="value" id="str">{{str}}</text>
</view>
<view class="item">
<text class="title">数值型数据:</text>
<text class="value" id="num">{{num}}</text>
</view>
<!-- <view class="item">
对象型数据:{{obj}}
</view> -->
<!-- <view class="item">
父组件传入的数组数据:{{arr}}
</view> -->
</view>
</template>
<script>
export default {
name:"my-component",
data() {
return {}
},
props: {
str: {
type: String
},
num: {
type: Number,
default: 0,
// TODO validator 暂未支持
// validator: (value):boolean => {
// // 设定条件:数字得小于3
// return value < 3
// }
},
// TODO Object
// obj: {
// type: Object,
// default: () => {}
// }
// TODO Array
// ,arr: {
// type: Array,
// default: () => []
// }
},
mounted() {
console.log('组件拿到的所有传入的数据', this.$props);
},
methods: {
}
}
</script>
<style>
.item{
padding: 5px;
flex-direction: row;
justify-content: space-between;
flex-wrap: wrap;
position: relative;
border-bottom: 0.1px solid #888;
}
.row{
width: 500rpx;
}
.title{
}
.value{
color: #222;
}
</style>
\ No newline at end of file
// uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
const PAGE_PATH = '/pages/state/props/props'
let page;
describe('/pages/state/props/props', () => {
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
page = await program.currentPage();
console.log('page', page);
await page.waitFor(1000);
});
it('检查往组件传递参数状态', async () => {
let str = await getMyComponentText("#str")
console.log('str-*--*-',str);
expect(str).toEqual("你好我是props.uvue组件传进的数据");
let num = await getMyComponentText("#num")
// console.log('num-*--*-',num);
expect(parseInt(num)).toEqual(1);
page.callMethod('addNum')
num = await getMyComponentText("#num")
// console.log('num-*--*-',num);
expect(parseInt(num)).toEqual(2);
});
});
async function getMyComponentText(param){
return await(await(await page.$('my-component')).$(param)).text();
}
\ No newline at end of file
<template>
<view class="content">
<my-component
:str="str"
:num="num"
:arr="arr"
:obj="obj"
></my-component>
<button class="btn" @click="addNum">数值+1</button>
</view>
</template>
<script>
import myComponent from './my-component.uvue';
type objType = {key:string}
export default {
data() {
return {
str:"你好我是props.uvue组件传进的数据",
num:1,
arr:[1,2,3],
obj:{"key":"value"} as objType,
}
},
components: {
"my-component":myComponent
},
methods: {
addNum(){
this.num ++
}
}
}
</script>
<style>
.content {
padding: 5px;
}
.btn {
margin-top: 5px;
}
</style>
// uni-app自动化测试教程: https://uniapp.dcloud.net.cn/worktile/auto/hbuilderx-extension/
const PAGE_PATH = '/pages/state/watch/watch'
let page;
describe('/pages/state/watch/watch', () => {
beforeAll(async () => {
page = await program.reLaunch(PAGE_PATH)
page = await program.currentPage();
console.log('page', page);
// await page.waitFor(3000);
});
it('检查数据是否渲染正确', async () => {
/*
num
addNum
subNum
oldNum
changeIndex
*/
let num = await getText('#num')
expect(num/1).toEqual(0);
let changeIndex = await getText('#changeIndex')
expect(changeIndex/1).toEqual(0);
page.callMethod('addNum')
num = await getText('#num')
expect(num/1).toEqual(1);
let oldNum = await getText('#oldNum')
expect(oldNum/1).toEqual(0);
changeIndex = await getText('#changeIndex')
expect(changeIndex/1).toEqual(1);
page.callMethod('addNum')
num = await getText('#num')
expect(num/1).toEqual(2);
oldNum = await getText('#oldNum')
expect(oldNum/1).toEqual(1);
changeIndex = await getText('#changeIndex')
expect(changeIndex/1).toEqual(2);
});
});
async function getText(param) {
return await (await page.$(param)).text();
}
\ No newline at end of file
<template>
<view class="content">
<view class="item">
<text>变量num的值:</text>
<text id="num">{{num}}</text>
</view>
<view class="btns">
<button @click="addNum" size="mini" type="primary">给变量num的值+1</button>
<button @click="subNum" size="mini" type="warn">给变量num的值-1</button>
</view>
<view class="item">
<text>上一次变化之前的值:</text>
<text id="oldNum">{{oldNum}}</text>
</view>
<view class="item">
<text>变化的次数:</text>
<text id="changeIndex">{{changeIndex}}</text>
</view>
</view>
</template>
<script>
export default {
data() {
return {
num:0,
changeIndex:0,
oldNum:0
}
},
watch: {
num(num,oldNum) {
console.log(num);
this.changeIndex ++
this.oldNum = oldNum
}
},
methods: {
addNum(){
this.num ++
},
subNum(){
this.num --
}
}
}
</script>
<style>
.content {
padding: 5px;
}
.item{
padding-top: 5px;
flex-direction: row;
}
.btns{
flex-direction: row;
width: 700rpx;
justify-content: space-around;
margin-top: 5px;
}
</style>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册