本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7584155
建立时间:2006年5月29日




[TurboGears]Testing Multi-user TurboGears Applications
软件技术

lhwork 发表于 2007/2/16 12:06:49

Lately I’ve started to write many unit tests for my secret turbogears project. My secret project, like many other web 2.0 applications, can have a lot of users logged in at the same time and the actions of one user can affect other users. The current testing tools provided by TurboGears do not give “one obvious way” to test multi-user scenarios. I came up last week with a simple class that will emulate a browser session of a single user against a cherrypy server. Its only task is actually to keep track of the visit cookie. This is a simple example of how I use it: def test_breaking_in(): user = BrowserSession() user.goto('/directory/for/members') assert 'You must login' in user.response assert '403' in user.status user.goto('/login?username=thesamet&password=secret') user.goto('/directory/for/members') assert 'Welcome to the members area' in user.response The BrowserSession object truly shines when your testcase includes two users (or more): def test_object_lock(): user1 = BrowserSession() user2 = BrowserSession() user1.goto('/login?username=user1&password=pass1') user2.goto('/login?username=user2&password=pass2') user1.goto('/edit?page=pagex') user2.goto('/edit?page=pagex') assert 'Page is locked by user1' in user2.response user1.goto('/edit?page=pagex') assert "page is locked by user1" not in user1.response and no - my secret project is not another wiki. I later found it very convenient to put test methods inside a TestCase object rather than many individual test functions. One of the benefits is that you can factor out the repeating code of the logins that appear in many tests to the setUp() method. In each test method, we will have new and fresh sessions: class TwoUsersTestCase(unittest.TestCase): def setUp(self): self.user1 = BrowserSession() self.user2 = BrowserSession() self.user1.goto('/login?username=user1&password=pass1') self.user2.goto('/login?username=user2&password=pass2')class SendPrivateMessageTestCase(TwoUsersTestCase): def test_send_message(self): self.user1.goto('/chat/send?to=user2&text=hello') self.user2.goto('/chat/receive') assert 'hello' in self.user2.response def test_flood_detection(self): for x in xrange(100): self.user1.goto('/chat/send?to=user2&text=hello') self.user2.goto('/chat/receive') assert 'user1 kicked out (flooding)' in self.user2.response Now I’ll share with you the BrowserSession code. Feel free to use it: import cherrypyfrom turbogears import testutildef cookie_header(morsel): """Returns a dict containing cookie information to pass to a server.""" return {'Cookie': morsel.output(header="")[1:]}class BrowserSession(object): def __init__(self): self.cookie_name = turbogears.config.get('visit.cookie.name', 'tg-visit') self.visit = None self.response, self.status = None, None def goto(self, *args, **kwargs): if self.visit: headers = kwargs.get('headers', {}) headers.update(cookie_header(self.visit)) kwargs['headers'] = headers testutil.createRequest(*args, **kwargs) if self.cookie_name in cherrypy.response.simple_cookie: self.visit = cherrypy.response.simple_cookie[self.cookie_name] self.response = cherrypy.response.body[0] self.status = cherrypy.response.status Ideas and suggestions are welcome!


阅读全文(2377) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.047 second(s), page refreshed 144753240 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号