这里有一些在写测试用例时可能用得上的方法和技巧。
# 1、选择节点的方法
开发者可以通过几种不同的方法来指定需要操作的节点。
# 通过节点的Path值来指定节点
Path的格式为:
{节点的className[节点属性=目标值|.......]}>或者.{节点的className[节点属性=目标值|.......]}.....
Path中节点由 {} 包围,className作为节点的名称,后方 [] 中包括节点的额外选择条件。额外选择条件可不填写,条件格式为 k=v ,多个条件之间用 | 连接,例如:
{a[k1=v1|k2=v2]}
表示该Path会选择className=a,同时满足属性k1=v1以及k2=v2的节点。
多个节点之间支持由 . 或者 > 连接,它们分别表示:
. 为选择当前节点的后代节点,即当前节点的所有后代节点都会作为备选。
> 为仅选择当前节点的子节点。
例如:
{a}.{b}>{c}
Path可以调用findPath方法传入调用,获取对应的NodeSelector实例对象。CaseContext实例对象或者NodeSelector实例对象都可以调用findPath方法,返回值为NodeSelector实例对象,如:
tmp = await c.findPath("{a}.{b}>{c}") //JavaScript
tmp = c.find_path("{a}.{b}>{c}") #Python
# 通过链式调用来指定节点
如果不想使用Path选择节点,还可以使用链式调用的方式:
tmp = await c.select((n)=>{ return (n["a"] || "") === "b" }).child({"c" : "d"}) //JavaScript
tmp = c.select(lambda n: n.get("a",None) == "b").child({"c" : "d"}) #Python
注意,JavaScript版本中 CaseContext实例对象的findPath方法以及select、child方法都是async function,调用时需要通过await 获取结果
# 通过图像识别来指定节点
测试框架提供图像识别的API,可以根据对目标图片的识别结果来获取其位置并进行交互。
- JavaScript版本调用方式:
let imgPath = path.join("img","1.png") //为了兼容跨平台,请使用系统库生成相对路径
tmp = await c.findImg(imgPath)
- Python版本调用方式:
img_path = os.path.join("img","1.png") #为了兼容跨平台,请使用系统库生成相对路径
tmp = c.find_img(img_path)
目标图片的路径,是基于测试Case路径的。如果目标图片的绝对路径为 ~/{workspace}/img/1.png的话,则findImg传入的imgPath则为img/1.png。
findImg函数返回的是ImgSelector实例对象,可以使用该对象对目标图片位置进行操作。
Tips
- 传入的imgPath由于跨平台原因,最好使用path.join方式进行连接。
- 图片识别的准确性可能会存在一定误差,如有问题请反馈给我们,谢谢。
# 2、操作节点的方法
测试框架目前支持点击、滑动等操作。通过调用ImgSelector实例对象以及NodeSelector实例对象的tap或者swipe方法,触发对应操作。每次操作之后,建议考虑游戏具体场景适当等待。 如果搜索节点时,未找到目标节点,则返回的ImgSelector实例对象或NodeSelector实例对象内容为空,这时触发事件会产生error。建议如果无法确定是否能获取到节点的时候,通过isEmpty()判断是否为空。 如果满足条件的节点有多个,则NodeSelector实例对象也会包括多个节点对象。这时触发事件,则会产生error。如果出现这种问题,建议调整选择条件。
# 3、完整的Case示例
- JavaScript版本:
const mini_game_test = require("mini_game_test")
const BaseCase = mini_game_test.BaseCase
const logger = mini_game_test.logger
class Test extends BaseCase {
async run(c) {
logger.info("start")
let tmp = null
//获取节点
tmp = await c.findPath("{laya.display.Stage[nodeType=laya.display.Stage|covered=false]}>{laya.display.Sprite[index=0|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=2|nodeType=laya.display.Sprite]}>{laya.display.Sprite[index=2|nodeType=laya.display.Sprite|covered=false]}")
//点击
await tmp.tap()
//等待
await c.sleep(3000)
let endStatus = false
for (let i = 0; i < 10; i++) {
await c.tap(0.5, 0.5)
await c.sleep(2000)
tmp = await c.findPath("{laya.display.Stage[nodeType=laya.display.Stage|covered=false]}>{laya.display.Sprite[index=0|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=5|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=3|nodeType=laya.display.Sprite|covered=false]}")
if (!tmp.isEmpty()) {
logger.info("game end")
endStatus = true
break
}
}
if (!endStatus) {
logger.info("game not end or game error")
return
}
tmp = await c.findPath("{laya.display.Stage[nodeType=laya.display.Stage|covered=false]}>{laya.display.Sprite[index=0|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=5|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=3|nodeType=laya.display.Sprite|covered=false]}")
await tmp.tap()
await c.sleep(3000)
tmp = await c.findPath("{laya.display.Stage[nodeType=laya.display.Stage|covered=false]}>{laya.display.Sprite[index=0|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=6|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=0|nodeType=laya.display.Sprite|covered=false]}")
await tmp.tap()
await c.sleep(3000)
tmp = await c.findPath("{laya.display.Stage[nodeType=laya.display.Stage|covered=false]}>{laya.display.Sprite[index=0|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=5|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=4|nodeType=laya.display.Sprite|covered=false]}")
await tmp.tap()
await c.sleep(3000)
tmp = await c.findPath("{laya.display.Stage[nodeType=laya.display.Stage|covered=false]}>{laya.display.Sprite[index=0|nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[nodeType=laya.display.Sprite|covered=false]}>{laya.display.Sprite[index=7|nodeType=laya.display.Sprite|covered=false]}")
await tmp.tap()
await c.sleep(3000)
}
}
logger.debug("start")
const t = new Test()
t.start()
- Python版本:
# -*- coding: utf-8 -*-
from mini_game_test_case_py.case.BaseCase import BaseCase
from mini_game_test_case_py.lib import config
from mini_game_test_case_py.lib import Asserts
from mini_game_test_case_py.lib import Logger
import time
class TestCase(BaseCase):
def run(self, c):
Logger.info("start case")
#获取开始按钮
start_node = c.find_path(
"{laya.display.Stage[covered=false]}>{laya.display.Sprite[index=0|covered=false]}>{laya.display.Sprite}>{laya.display.Sprite[index=2|covered=false]}")
#判断开始按钮是否存在
Asserts.assert_nodeselector_exists(start_node)
#点击
start_node.tap()
c.sleep(6000)
start_time = time.time()
endStatus = False
#循环判断paihang_node是否出现
while time.time() - start_time < 30 :
c.tap(0.5, 0.5, is_per=True)
time.sleep(1)
paihang_node = c.find_path("{laya.display.Stage[covered=false]}>{laya.display.Sprite[index=0|covered=false]}>{laya.display.Sprite[index=5|covered=false]}>{laya.display.Sprite[index=3|covered=false]}")
if not paihang_node.is_empty():
Logger.info("game end")
endStatus = True
break
if not endStatus:
Logger.info("game end error")
return
tmp = c.find_path("{laya.display.Stage[covered=false]}>{laya.display.Sprite[index=0|covered=false]}>{laya.display.Sprite[index=5|covered=false]}>{laya.display.Sprite[index=3|covered=false]}")
Asserts.assert_nodeselector_exists(tmp)
tmp.tap()
c.sleep(6000)
tmp = c.find_path("{laya.display.Stage[covered=false]}>{laya.display.Sprite[index=0|covered=false]}>{laya.display.Sprite[index=6|covered=false]}>{laya.display.Sprite[index=0|covered=false]}")
Asserts.assert_nodeselector_exists(tmp)
tmp.tap()
c.sleep(6000)
tmp = c.find_path("{laya.display.Stage[covered=false]}>{laya.display.Sprite[index=0|covered=false]}>{laya.display.Sprite[index=5|covered=false]}>{laya.display.Sprite[index=4|covered=false]}")
Asserts.assert_nodeselector_exists(tmp)
tmp.tap()
c.sleep(6000)
tmp = c.find_path("{laya.display.Stage[covered=false]}>{laya.display.Sprite[index=0|covered=false]}>{laya.display.Sprite[covered=false]}>{laya.display.Sprite[index=7|covered=false]}")
Asserts.assert_nodeselector_exists(tmp)
tmp.tap()
c.sleep(6000)
Logger.info("end test")
t = TestCase()
t.start()