一个菜鸟测试工程师的简易自动化测试框架

上一篇 / 下一篇  2012-09-07 11:24:05 / 个人分类:自动化测试

P9b6d!F:?0  引子

T}YJlr6uH&y-v0

lp ]RjI0  作为一个无 dev 经验的 tester 来说,目前遇到许多新的问题,关于 tester 以后的人员基本素质的构成,现在也有许多说法,在这里,不想过多的铺开讨论了。 作为一个 tester,本身当然必须对test这件事情感兴趣,才能把工作做好。 有的人天生喜欢找茬,喜欢提意见,在我看来,就是一个不错的 tester 的料。 当你天天对着同一个产品的不同版本不停的测试的时候,自然会产生一些怨言,由此产生懈怠。51Testing软件测试网 [ Z`X4A*mhQI3UT!I

51Testing软件测试网A2W6z._Z4b5O-g

   “某些功能点我都连着测试了 N 个版本了,肯定不会出错了” “这种基本功能点,怎么可能出错”这样的论调是很有可能产生的。于是,一个 tester 很有可能在某次 release 的过程中,经验主义的放过了某些功能点的测试。 几天后,一个用户反馈上来,那个功能点出了问题.........

CSvz9@051Testing软件测试网*Fk2V k?A

  “偷懒”这个词语,在测试过程中,不应该算一个贬义词(当然了,故意漏过功能点不测试,不在此列)。因为“偷懒”催生新的技术,“偷懒”节省更多的时间。 我相信,自动化测试就是这样来的。

n GB\#|BvA0

E[|9Y)z/f?0  正题51Testing软件测试网WQF$b8Z(k

+r:mE.n}O;Q4f0u+Q0  任何事情都可以分解为很小的部分,让我们先分析一下,手工执行测试案例的一个过程:51Testing软件测试网yK3Lj+?v6z ~

51Testing软件测试网5WCZ-zh&~#g;Y{%B

  打开被测软件51Testing软件测试网9q+ZYCj

\$_#f+AN b~@0  执行测试案例

.v aJY_ T4\ X0

5Ej1D d9Xk2dvb0  给出测试结果

3K'M{XS/kt0

B_Y_fEA)rd0  然后,我们不断重复这个过程。 最后给出测试报告。

O$@-P/g_%Y7u051Testing软件测试网*X8@ P{U\"o

  显然,我们的自动化测试也要满足上面的这个过程中的所有要求。 既然是自动化,首先要求是所有的测试用例可以无人值守运行;其次,每个测试用例都由机器来模拟人对软件的操作;第三,某个测试用例失败不能影响其他测试用例的继续执行;第四,测试数据和测试用例最好分离开来;最后一点,测试结束之后,给个报告或者给个图告知测试结果。

x?!Bh4k]0

W4LU&Q)Xm/f:@,oM0  根据上面的分析,我们逐个来一一解决,当然了,本篇都是很初级的解决方式,相信有许多大牛会有更好的方式来解决。

*df*j`1[N[0

A/\{X*nwX0  无人值守运行,那么 python 的 unittest 的框架就能达到这个目的。51Testing软件测试网2L#C m"\L,I(t)l$P3?eK

51Testing软件测试网"UEk'XW9jt&M5NZ)U

  模拟人的操作, selenium 可以胜任。

g"Nf&d(N,m0

hB6@Q8cU0  测试用例间无影响, 同1

e#lypx7FDg6i051Testing软件测试网,a2w M@a A Z1p

  数据分离, 那把测试数据都扔xml里。51Testing软件测试网C(z4_-C6Q[Uy

8d3ga[:K7c0  待完善 (本例中 只是在部分方法中添加错误提示)

1i%o;u#{5o051Testing软件测试网1AB?FA]U{(M?

  开始动手

m5T-a5qj051Testing软件测试网$~S5\P,g/c

  对 python 的 unittest 进行一些小手术,当然了,如果只追求简单,直接用也行。51Testing软件测试网2V,DkRM&~ r

def assertLogEqual(self, arg1, arg2):51Testing软件测试网i)T r ^4Pg
print "[assertLogEqual('"+arg1+"', '"+arg2+"')]: "51Testing软件测试网 x K0fjw+K5D
if arg1 != arg2:
,y)p)t!G|0self.anyfailure = True
?2yAPRP0print " -> Failed: not equal"51Testing软件测试网qXDd+hMu!|!p
self.result_note = " '%s' and 's%' is not equal\n "%(arg1,arg2)
%nxS%Yp~@3]h X6XF1o0else:51Testing软件测试网t ? y^/a.RH X
print " ->OK"
yAZ7}:~ L5Afj h0self.result_note = "%s OK\n" % self.result_note51Testing软件测试网f)~.r'Qq
self.assertEqual(arg1, arg2)51Testing软件测试网8w"WnU7x8@q
def assertLogTrue(self, arg1, note=""):
KV2_ ^6UA E0print "[assertLogTrue("+str(arg1)+")]: "+note
v4c ]~5Q Dr0if arg1 is False:51Testing软件测试网gb F'av"E|F
self.anyfailure = True51Testing软件测试网rJZ[MO
print " -> Failed: Excepting True"51Testing软件测试网Q?5V"K!OF*c aj6mK
self.result_note = " %sError: %s\n " % (self.result_note, note)
!VTiDe~c0else:
I-mw q5B8I5w6wV2F0print " ->OK"
*y$W-KI2DLSv0self.resulte_note = "%s OK\n" % self.result_note
&VrdqTy Bk0self.assertTrue(arg1)51Testing软件测试网|$Oo HPN}
def assertLogFalse(self, arg1, note=""):
S.j#j M(d4L Mt0print "[assertLogFalse("+str(arg1)+")]: "+note51Testing软件测试网sD(k,KnIn
if arg1 is True:
fXZ"qTm7t-F0print " ->FAILED: Expecting False."
n+?0Dw$g ^0self.anyfailure = True51Testing软件测试网 ^ V+`m5]/M
self.result_note = "%sError: %s\n" % (self.result_note, note)51Testing软件测试网Y!d9we:S3IU
else:
#g/V&M3W \/fhdQV0self.result_note = "%sOK\n" % self.result_note
fej8C'z%PBd+r0print " ->OK"
e U7s)^6?u H{0self.assertFalse(arg1)
p^o^k YF X l0
51Testing软件测试网]P+u%r*W`/U!y J

  自己新建一个类,继承unittest,然后修改必要的一些方法,并添加部分方法,譬如设置testName啊,设置标记值来标记case知否执行结束啊。这些都是可以根据自己喜好来加入的方法。51Testing软件测试网 p6G)Rc7s2Y!IM%I\

xM%p{;B d0

z/@%_ OO*f3l h0
def setTestName(self, tname):51Testing软件测试网J(i _+^)[ O
self.testname = tname
GNl)g1_,bF |"_)q"fr0def getTestName(self):51Testing软件测试网*i%K?hO4cvW
return self.testname51Testing软件测试网i| Y0O btp
def setCompleted(self):51Testing软件测试网B Nd#e;t7K,]#H
self.completed = True51Testing软件测试网-m N!}aQ-M
def isCompleted(self):
,X2@ Y F#w{ J`h%^z0return self.completed

1l4V$K(|'Pt%`N0  对于unittest框架的修改 就写这么多。51Testing软件测试网/O-xh$Rk)[+}Y8`Rm

fl A&U[e7M0  对selenium的基本方法做一些小改动,动机优化 unittest 框架一致,只是为了让你的用例跑起来的时候更加让人理解。我们相当于在 selenium 的基本方法外面又封装了一层。下面是部分方法示例:51Testing软件测试网(o*F ^Sl&^.Mm^

\-j N]1dWPE0M r&M0

J)e&Y0l/f$Ha0
def open(self,url):51Testing软件测试网6\M0u%xR[ Cs
self.sel.open(url)51Testing软件测试网 oIEy8k.`A
def GetValue(self, element):51Testing软件测试网*[8q S^ud'c
value = self.sel.get_value(element)
^:eZM0M J`/vm#B:c1u0self.assertLogTrue(True, "Value for element %s is %s" %(element, value))51Testing软件测试网Ko-uN?#Q%g0zGG[
return value
4h!tb(?2u?8S*`0def isTextPresent(self, text):
'X0v.Qh^4h4dq}7s0val = self.sel.is_text_present(text)
*I cX&P1mS0if val is False:
$Ki7[.e/uk0self.assertLogTrue(val, note="error occured *************" + text +\
c/V&ot'M.nu"I,cK0" not found")51Testing软件测试网U,e*VTR
else:51Testing软件测试网C/^hpcC
print 'present (%s,%s)' % (text,val)
0K6}we"V0F0return val
8[[#v8c*~0def Select(self, element, selection):
P6EB,T!\4I B KG0if self.isElementPresent(element):
Wgc9XJf0self.sel.select(element, selection)51Testing软件测试网 ~,NB2Hk
def Check(self, element):
7L]qQX5S iY0if self.isElementPresent(element):51Testing软件测试网{&g$pXy"L;L
self.sel.check(element)51Testing软件测试网c z Mn#u"y
def Type(self, element, text):
.ZZYO-|g8z9{m5fL0if self.isElementPresent(element):
4x\8jB)@#a \ _T3x$c3f0self.sel.type(element, text)

j~UBh!SROi^_0  测试数据分离,这个做的非常简单,就是把期望值和控件位置作为测试数据放入 xml 中。51Testing软件测试网N4HL+qh^RH\ `

5m'K0f y3F Vy051Testing软件测试网&j6c |I1Y%|X&_

GWEB51Testing软件测试网5ht&vd-Kz.|
link51Testing软件测试网)o\0|tZ bY CL:a
//span[text()="Web"]
(p?R [8c;o+O qO0Web
;w$gS Dt c\ u#W0GIMAGES51Testing软件测试网8r4r[j$VC7N
link
,m+Q6F.iJ:[m8a p"w0//span[text()="Images"]51Testing软件测试网@ tr'@#|}(yR C R} W"L
Images

4uPQ0N{j,Jw0  name 表示控件名字,type 为控件的类型,locator 表示控制位置,expect_value 表示期望值。51Testing软件测试网loM6bV9t:W

51Testing软件测试网*qu2UnN8xV1]F

  读取 xml 的内容。这段代码属于我现学现卖,直接看了一下 python 对 xml 的支持,然后自己捣鼓了一下就写出来了,可以获取自己需要的 xml 里面的数据。

VI?&iY,A4@#k/@-N051Testing软件测试网)f;i)E*wsZ~l(d

51Testing软件测试网b)h.NRJKG9m

from xml.dom import minidom
Z o[zZ2bgu?0class PageData():
7wv,w1[,qRA0def __init__(self, page_name, file):
~Y*jQ b0self.name = page_name51Testing软件测试网'c3c+?Q?6@(IL
self.data = minidom.parse(file)51Testing软件测试网 | g,hy3a7IMo
self.xpth_dict = self.XML_Dict()
7H){,J;Abj&Ai0def XML_Dict(self):51Testing软件测试网7q}X(G4xiM:WF
xpath_dict = {}51Testing软件测试网PUY7b7bb6UZ _,o
for i in self.data.getElementsByTagName(self.name):51Testing软件测试网Q5XjO EB:f
xpath_dict[str(i.childNodes[1].firstChild.nodeValue)] = \51Testing软件测试网I4L3K9XF6n!U!\Z!d
[str(i.childNodes[5].firstChild.nodeValue),\51Testing软件测试网%cp1S0C4tg^/c
str(i.childNodes[7].firstChild.nodeValue)]
u+AtH)Gx-w/M0return xpath_dict51Testing软件测试网4OR5w _f
def GetLocator(self, object_name):
A6Nz*g*K)a0return self.xpth_dict[object_name][0]51Testing软件测试网Sk$t3_IlP
def GetValue(self, object_name):
M6H`@)c*}5D0return self.xpth_dict[object_name][1]

6S{"][7ih/{0  最后,主程序里面,我们就能用下面的方式,执行我们本来已经设计好的案例。

-`&F["]\'^0

#AQ'h6QTg-d/](X051Testing软件测试网5q rA5zL/@

def testAutoCompleteFunctionMouseMove(self):
N ];veQ|&I*F7e0'''test the function of auto complete. case 2: when user move mouse to the suggestion, there will be a link '''51Testing软件测试网#t^v6y gf;D
self.initTest("testAutoCompleteFunctionMouseMove")
Q6J]:h~0self.open('http://www.google.com/ncr')51Testing软件测试网7w]^$r/i^
GoogleHomePage = data_parser.PageData("GoogleHomePage", self.data_file)51Testing软件测试网vyrq&}6~h
self.Type(GoogleHomePage.GetLocator('SEARCHTEXT'), 's')51Testing软件测试网2H^ CHbgF'tbV"Y
GoogleAutoComplete = data_parser.PageData("AutoCompleteCase", self.data_file)51Testing软件测试网| r c5wQ6i'@
self.isElementPresent(GoogleAutoComplete.GetLocator("SUGGESTIONFIELD"))51Testing软件测试网z.{ @sU,[
time.sleep(10)51Testing软件测试网xc4c!~M0T Mi#L/u*P
self.MouseMove(GoogleAutoComplete.GetLocator("SUGGESTIONONEFORS"))51Testing软件测试网u,^/K w/Z7pd
expect_text = "I'm Feeling Lucky ?"
XUBh2Z0self.assertLogTrue(self.isTextPresent(expect_text), "The text %s has been displayed" %expect_text)51Testing软件测试网3cKA G M)cn!rA
self.MouseMove(GoogleAutoComplete.GetLocator("SUGGESTIONTWOFORS"))
j#FA et0time.sleep(10)51Testing软件测试网9[g _&ih,jL-PT F
self.assertLogTrue(self.isTextPresent(expect_text), "The text %s has been displayed" %expect_text)
y3r1ao%h @W}0self.endTest()
51Testing软件测试网YZ}5a{W DA(JD:h

  这样,一个相当简易的自动化测试框架基本完工。可以完善的地方实在太多了,希望有志之士去完善吧,加入些新功能,譬如错误出现的时候截图,然后统计测试用例总数以及通过的数量。

G/B(wl+Jk&D9L;f0

[!K@!xErW-f0  后记

]/ZZ1x3`!FT8P]1n%sQ3z051Testing软件测试网%s|"UtR8G muX

  作为一个菜鸟测试工程师,没有任何的开发经验,搞出这个东西还是有点小激动的,也激发了本人对许多事情的兴趣。 以后希望能有更好的 test frame. 去学习去创造。

|j\] K-P051Testing软件测试网 d x"yk~)K2B2c

TAG:

虫师 引用 删除 fnngj   /   2014-02-14 18:50:46
写得太笼统,修改的文件的代码也讲清楚。
 

评分:0

我来说两句

Open Toolbar