摘要:使用任务分发系统Gearman分布式执行Calabash的自动化测试用例,可以达到并行测试手机APP的目的。

背景介绍

Gearman

Gearman是一个分发任务的程序框架,可以用在各种场合,与Hadoop相比,Gearman更偏向于任务分发功能。它的 任务分布非常简单,简单得可以只需要用脚本即可完成。

下载ruby

Calabash

Calabash-android是支持android的UI自动化测试框架,PC端使用了cucumber框架,通过http和json与模拟器和真机上安装的测试apk通信,测试apk调用robotium的方法来进行UI自动化测试,支持webview操作。

calabash脚本以 使用calabash测试开源中国Android客户端 为例。

Gearman安装和执行测试

Ubuntu上安装Gearman

$ sudo apt-get install gearman-job-server
$ gearmand -V

gearmand 1.0.6 - https://bugs.launchpad.net/gearmand

$ sudo apt-get install gearman-tools
$ gearman -H

运行Gearman并发执行Calabash测试用例

启动gearman job server,作为后台服务运行:

$ gearmand -d

启动两个worker,每个woker代表一个手机测试设备(tester),woker始终不退出,且没有任何打印:

$ gearman -w -f tester -- ./test-case.sh NEXUS-7 testdata-aa.bashrc
$ gearman -w -f tester -- ./test-case.sh HUAHEI-8860 testdata-bb.bashrc

分发测试用例到各个worker,收集到所有测试打印后,即完成测试:

./run-suite.sh @BVT

实时查看测试结果,任何一个worker测试完一个用例,测试结果会立即打印出来:

tail -f /tmp/test-result

并发测试的效果:
理论上如果顺序执行测试所有用例要10个小时,那么只要准备10个手机,每个手机对应启动一个worker:tester,测试时间将缩短到最少1个小时。

下面的脚本是在同一台Ubuntu电脑上,利用多个USB口连接多个手机来并发测试,
如果要在多台电脑上执行并发测试,那要考虑这多台电脑如何获取同一份apk和calabash脚本,可以考虑从一个公共的url去wget。

Gearman测试脚本

test-case.sh

从stdin接收到的calabash测试脚本文件路径,调用calabash-android完成测试,再作为client调用printer

#!/bin/bash
if [ x$2 == x ]
then
echo "usage: $0 device-id testdata-xx.bashrc"
echo " device-id get from: adb devices"
exit 1
fi
read line
echo $0 $1 $2
uuid=`uuidgen`
d1=`date +%T`
suite_path=$HOME/git/oschina/android-app/calabash
apk_path=$HOME/git/oschina/android-app/bin/oschina-android-app.apk
echo "test result in /tmp/${uuid}"
echo $d1 at `hostname`:$1 >> /tmp/${uuid}
mkdir -p $HOME/$1
cd $HOME/$1
export ADB_DEVICE_ARG=$1
. $src/$2
calabash-android run $apk_path -r $suite_path/features/ $line 2>&1 | tee -a /tmp/${uuid}
d2=`date +%T`
echo $d2 at `hostname`:$1 >> /tmp/${uuid}
failed=`grep "Failing Scenarios" /tmp/${uuid} | wc -l`
if [ $failed == 0 ]
then
echo "===PASS=== : $line" >> /tmp/${uuid}
else
echo "===FAIL=== : $line" >> /tmp/${uuid}
fi
gearman -f printer < /tmp/${uuid}
rm -f /tmp/${uuid}

从stdin接收测试结果,并添加到文件/tmp/test-result

#!/bin/bash
while read line
do
echo "$line" >> /tmp/test-result
done
case_count=`cat /tmp/case_count`
finished=`egrep "===(PASS|FAIL)===" /tmp/test-result | wc -l`
echo -n "Progress:" $finished "/ $case_count [" >> /tmp/test-result

for ((i=0; i<$finished; i++ ))
do
echo -n ">" >> /tmp/test-result
done
let unfinished=$case_count-$finished
for ((i=0; i<$unfinished; i++ ))
do
echo -n "." >> /tmp/test-result
done
echo -en "]\n" >> /tmp/test-result

run-suite.sh

作为client,后台一次分发所有calabash脚本到tester,并启动woker: printer,直到收到所有测试结果打印才退出

#!/bin/bash
if [ x$1 == x ]
then
echo "usage:" $0 "@BVT|@nightly|all|failed"
exit 1
fi

suite_path=$HOME/git/oschina/android-app/calabash
uuid=`uuidgen`

if [ "$1" == "all" ]
then
find $suite_path -name "*.feature" > /tmp/${uuid}
elif [ "$1" == "failed" ]
then
if [ -f /tmp/failed ]
then
cat /tmp/failed > /tmp/${uuid}
else
touch /tmp/${uuid}
fi
elif [[ "$1" == @* ]]
then
grep $1 $suite_path -rl | grep ".feature$" > /tmp/${uuid}
fi

case_count=`cat /tmp/${uuid} | wc -l`
echo $case_count > /tmp/case_count
if [ $case_count == 0 ]
then
echo "NO case to run, exit." | tee /tmp/test-result
rm -f /tmp/${uuid}
exit 1
fi

echo "total $case_count cases." | tee /tmp/test-result

i=0
while read line
do
let i+=1
echo "send No.$i case --- $line"
echo $line | gearman -b -f runcase
done < /tmp/${uuid}
rm -f /tmp/${uuid}

gearman -w -c $case_count -f printer -- ./print-result.sh $case_count
cat /tmp/test-result
grep "===FAIL===" /tmp/test-result | awk '{print $3}' > /tmp/failed
echo "" > /tmp/summary
echo "=================test result summary================" 2>&1 | tee -a /tmp/summary
grep "===PASS===" /tmp/test-result 2>&1 | tee -a /tmp/summary
grep "===FAIL===" /tmp/test-result 2>&1 | tee -a /tmp/summary
fails=`grep "===FAIL===" /tmp/test-result | wc -l`
if [ $fails == 0 ]
then
echo -e "\033[32;1;7mPASS\033[0m :" `grep "===PASS===" /tmp/test-result | wc -l` 2>&1 | tee -a /tmp/summary
else
echo -e "\033[31;1;7mFAIL\033[0m :" `grep "===FAIL===" /tmp/test-result | wc -l` 2>&1 | tee -a /tmp/summary
fi
echo "TOTAL: $case_count" 2>&1 | tee -a /tmp/summary
cat /tmp/summary >> /tmp/test-result


↙↙↙阅读原文可查看相关链接,并与作者交流