我正在使用 unnitest.TestCase 测试测试 Django 应用程序。
if test['auth']:
full_url = '{}/{}'.format(host, test['url'])
request = urllib2.Request(full_url)
cj = cookielib.CookieJar()
opener = urllib2.build_opener(urllib2.HTTPCookieProcessor(cj))
urllib2.install_opener(opener)
urlh = urllib2.urlopen(full_url)
html = urlh.read()
doc = BeautifulSoup(html)
csrf_input = doc.find(attrs = dict(name = 'csrfmiddlewaretoken'))
csrf_token = csrf_input['value']
params = urllib.urlencode(dict(username = test['username'], password=test['password'],
csrfmiddlewaretoken = csrf_token, user=CustomUser.objects.get(id=2), next=test['url']))
urlh = urllib2.urlopen(full_url, params)
output = urlh.read()
print 'Checking {} for "{}" string at {}.'.format(test['url'], test['test_string'], host)
print output
if test['test_string'] in output:
return True
else:
return False
进入此页面的测试数据如下所示:
{
'url' : '/manager/',
'test_string' : 'Manage your jobs',
'comment' : 'testing string in page',
'hosts' : (hosts['test'],),
'auth' : True,
'username' : 'poster',
'password' : 'poster',
'active' : True,
},
*为了完整起见:hosts['test'] 等于 'http://:' 它通过for host in hosts: ...调用 http_string_tester
我要检查的页面要求用户登录(此页面 url 是“/manager/”):
@login_required(login_url='/auth/login/')
def index(request):
# Get list of jobs that were created by the user
job_list = Job.objects.filter(poster_id=request.user.id)
return render_to_response(
'manager/index.html',
{
'page_title' : 'Manager', # title for html page
'app_name' : SITENAME, # Site's proper name
'job_list' : job_list,
'request' : request,
},
context_instance = RequestContext(request),
)
登录视图 ('/auth/login/') 如下所示:
def dologin(request):
message = 'blah'
user = []
if request.method == 'POST':
username = request.POST['username']
password = request.POST['password']
user = authenticate(
username = username,
password = password,
)
if user is not None and hasattr(user, 'verified'):
if user.verified and user.is_active:
message = 'authenticated'
login(request, user)
# This section seems to be required so that I can redirect properly in
# the browser but in the test it seems to be a hindrance.
if request.POST['next'] is not None:
print 'NEXT is '+str(request.POST['next'])
return HttpResponseRedirect(request.POST['next'])
else:
return HttpResponseRedirect('/')
# .............. #
# The rest
if request.method == 'GET' and 'next' in request.GET:
next = request.GET['next']
else:
next = None
print 'NEXT is '+str(next)
return render_to_response(
'auth/login.html',
{
'page_title' : 'Log in to {}'.format(SITENAME),
'app_name' : SITENAME,
'message' : message,
'next' : next,
},
context_instance = RequestContext(request),
)
当我运行测试时,我在日志中得到以下信息(来自 .manage.py runserver):
Development server is running at http://<hostname:port>/
Quit the server with CONTROL-C.
[15/Apr/2013 08:21:53] "GET /manager/ HTTP/1.1" 302 0
NEXT is /manager/
[15/Apr/2013 08:21:53] "GET /auth/login/?next=/manager/ HTTP/1.1" 200 2973
[15/Apr/2013 08:21:53] "POST /manager/ HTTP/1.1" 302 0
NEXT is /manager/
[15/Apr/2013 08:21:53] "GET /auth/login/?next=/manager/ HTTP/1.1" 200 2973
因此,看来我能够到达 /manager/ 但使用 302(重定向 - 这是有道理的),然后我被重定向到 /auth/login/?next=/manager/ 将我发送到 / manager/ 但再次返回 302 到 /auth/login/?next.... 这样它就告诉我它不接受此用户已登录。我已经验证当我点击我的应用程序时整个过程都有效。这些是步骤:
使用网络浏览器,我转到 http://:/manager/ 这会将我重定向到 http://:/auth/login/?next=/manager/ 我使用 'poster:poster' 登录的地方然后将我重定向到http://:/manager/ 我可以按预期看到页面。
FWIW,我的一项测试只是进入登录页面,可以登录并从输出中提取预期信息,但这似乎在这里不起作用。
我正在寻求一些指导。使用浏览器可以正确重定向我,但这个 urllib2 调用似乎没有这样做。我希望有人能解释为什么这不能像我预期的那样工作。如果您需要任何进一步的信息,请告诉我。
更新:
响应标头分别来自每个打开的:
HEADERS are Date: Mon, 15 Apr 2013 13:42:33 GMT
Server: WSGIServer/0.1 Python/2.7.3
Vary: Cookie
Content-Type: text/html; charset=utf-8
Set-Cookie: csrftoken=TYEE6upwq20wNoobztYWHlIjnIQ8qc2u; expires=Mon, 14-Apr-2014 13:42:33 GMT; Max-Age=31449600; Path=/
PARAMS are username=poster&csrfmiddlewaretoken=TYEE6upwq20wNoobztYWHlIjnIQ8qc2u&password=poster&user=poster&next=%2Fmanager%2F
RESPONSE HEADERS are Date: Mon, 15 Apr 2013 13:42:33 GMT
Server: WSGIServer/0.1 Python/2.7.3
Vary: Cookie
Content-Type: text/html; charset=utf-8
Set-Cookie: csrftoken=TYEE6upwq20wNoobztYWHlIjnIQ8qc2u; expires=Mon, 14-Apr-2014 13:42:33 GMT; Max-Age=31449600; Path=/