Python 在Selenium测试中,等待最终一致性传播需要多长时间?
我正在尝试创建测试,以验证在使用Selenium时我的实体是否保存在数据库中。 当我手动输入表单数据时,代码工作正常,但自动测试失败 当我在代码的post函数中设置断点时,我可以看到保存记录后客户数量发生了变化。 我读 我使用的是一个祖先查询,我认为它具有很强的一致性,所以我不知道为什么会出现这些问题 据我所知,由于最终的一致性,测试失败了,解决这个问题的方法是更改伪随机HRConsistencyPolicy设置Python 在Selenium测试中,等待最终一致性传播需要多长时间?,python,google-app-engine,selenium-webdriver,Python,Google App Engine,Selenium Webdriver,我正在尝试创建测试,以验证在使用Selenium时我的实体是否保存在数据库中。 当我手动输入表单数据时,代码工作正常,但自动测试失败 当我在代码的post函数中设置断点时,我可以看到保存记录后客户数量发生了变化。 我读 我使用的是一个祖先查询,我认为它具有很强的一致性,所以我不知道为什么会出现这些问题 据我所知,由于最终的一致性,测试失败了,解决这个问题的方法是更改伪随机HRConsistencyPolicy设置 policy = datastore_stub_util.PseudoRandom
policy = datastore_stub_util.PseudoRandomHRConsistencyPolicy(probability=1)
当我再次运行测试时,我得到了相同的错误
还有人建议,如果我等待一段时间,最终的一致性将有时间传播。
这对测试也不起作用
创建这些测试有什么不对
> /Users/Bryan/work/GoogleAppEngine/dermalfillersecrets/main.py(130)post()
-> customer.put()
(Pdb) l
125 customer.phone = self.request.get('id_phone')
126 customer.zipcode = int(self.request.get('id_zip'))
127 # show original number of customer to show the code works
128 starting_customer_count = Customer.query(ancestor=client.key).count()
129 import pdb; pdb.set_trace()
130 -> customer.put()
131 final_customer_count = Customer.query(ancestor=client.key).count()
132 import pdb; pdb.set_trace()
133 query_params = {'leadbook_name': leadbook_name}
134 self.redirect('/?' + urllib.urlencode(query_params))
135
(Pdb) starting_customer_count
19
(Pdb) c
> /Users/Bryan/work/GoogleAppEngine/dermalfillersecrets/main.py(133)post()
-> query_params = {'leadbook_name': leadbook_name}
(Pdb) l
128 starting_customer_count = Customer.query(ancestor=client.key).count()
129 import pdb; pdb.set_trace()
130 customer.put()
131 final_customer_count = Customer.query(ancestor=client.key).count()
132 import pdb; pdb.set_trace()
133 -> query_params = {'leadbook_name': leadbook_name}
134 self.redirect('/?' + urllib.urlencode(query_params))
135
136 config = {}
137 config['webapp2_extras.sessions'] = {
138 'secret_key': 'my-super-secret-key',
(Pdb) final_customer_count
20
实体也会显示在数据存储查看器中
然而,我的考试一直不及格
$ nosetests --with-gae
test_guest_can_submit_contact_info (dermalfillersecrets.functional_tests.NewVisitorTest) ... FAIL
======================================================================
FAIL: test_guest_can_submit_contact_info (dermalfillersecrets.functional_tests.NewVisitorTest)
----------------------------------------------------------------------
Traceback (most recent call last):
File "/Users/Bryan/work/GoogleAppEngine/dermalfillersecrets/functional_tests.py", line 75, in test_guest_can_submit_contact_info
self.assertNotEqual(orig_customer_count, final_customer_count)
AssertionError: 0 == 0
这是functional_tests.py文件内容:
import os, sys
sys.path.append("/usr/local/google_appengine")
sys.path.append("/usr/local/google_appengine/lib/yaml/lib")
sys.path.append("/usr/local/google_appengine/lib/webapp2-2.5.2")
sys.path.append("/usr/local/google_appengine/lib/django-1.5")
sys.path.append("/usr/local/google_appengine/lib/cherrypy")
sys.path.append("/usr/local/google_appengine/lib/concurrent")
sys.path.append("/usr/local/google_appengine/lib/docker")
sys.path.append("/usr/local/google_appengine/lib/requests")
sys.path.append("/usr/local/google_appengine/lib/websocket")
sys.path.append("/usr/local/google_appengine/lib/fancy_urllib")
sys.path.append("/usr/local/google_appengine/lib/antlr3")
import unittest
from selenium import webdriver
from google.appengine.api import memcache
from google.appengine.ext import db
from google.appengine.ext import testbed
import dev_appserver
from google.appengine.tools.devappserver2 import devappserver2
class NewVisitorTest(unittest.TestCase):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
#self.testbed.setup_env(app_id='dermalfillersecrets')
self.testbed.init_user_stub()
self.testbed.init_datastore_v3_stub()
self.testbed.init_memcache_stub()
# setup the dev_appserver
APP_CONFIGS = ['app.yaml']
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3)
def tearDown(self):
self.browser.quit()
self.testbed.deactivate()
def test_guest_can_submit_contact_info(self):
from main import Client, Customer
# below query didn't work because of eventual consistency
#query = Customer.query()
client = Client.query( Client.name == "Bryan Wheelock").get()
orig_customer_count = Customer.query(ancestor=client.key).count()
self.browser.get('http://localhost:8080')
self.browser.find_element_by_name('id_name').send_keys("Kallie Wheelock")
self.browser.find_element_by_name('id_street').send_keys("123 main st")
self.browser.find_element_by_name('id_phone').send_keys('(404)555-1212')
self.browser.find_element_by_name('id_zip').send_keys("30306")
self.browser.find_element_by_name('submit').submit()
# this should return 1 more record
import time; time.sleep(10)
final_customer_count = Customer.query(ancestor=client.key).count()
self.assertNotEqual(orig_customer_count, final_customer_count)
assert(Customer.query(Customer.name == "Kallie Wheelock").get())
# Delete the Customer record
Customer.query(Customer.name =="Kallie Wheelock").delete()import os, sys
sys.path.append("/usr/local/google_appengine")
sys.path.append("/usr/local/google_appengine/lib/yaml/lib")
sys.path.append("/usr/local/google_appengine/lib/webapp2-2.5.2")
sys.path.append("/usr/local/google_appengine/lib/django-1.5")
sys.path.append("/usr/local/google_appengine/lib/cherrypy")
sys.path.append("/usr/local/google_appengine/lib/concurrent")
sys.path.append("/usr/local/google_appengine/lib/docker")
sys.path.append("/usr/local/google_appengine/lib/requests")
sys.path.append("/usr/local/google_appengine/lib/websocket")
sys.path.append("/usr/local/google_appengine/lib/fancy_urllib")
sys.path.append("/usr/local/google_appengine/lib/antlr3")
import unittest
from selenium import webdriver
from google.appengine.api import memcache
from google.appengine.ext import db
from google.appengine.ext import testbed
import dev_appserver
from google.appengine.tools.devappserver2 import devappserver2
class NewVisitorTest(unittest.TestCase):
def setUp(self):
self.testbed = testbed.Testbed()
self.testbed.activate()
#self.testbed.setup_env(app_id='dermalfillersecrets')
self.testbed.init_user_stub()
self.testbed.init_datastore_v3_stub()
self.testbed.init_memcache_stub()
# setup the dev_appserver
APP_CONFIGS = ['app.yaml']
self.browser = webdriver.Firefox()
self.browser.implicitly_wait(3)
def tearDown(self):
self.browser.quit()
self.testbed.deactivate()
def test_guest_can_submit_contact_info(self):
from main import Client, Customer
client = Client.query( Client.name == "Bryan Wheelock").get()
orig_customer_count = Customer.query(ancestor=client.key).count()
self.browser.get('http://localhost:8080')
self.browser.find_element_by_name('id_name').send_keys("Kallie Wheelock")
self.browser.find_element_by_name('id_street').send_keys("123 main st")
self.browser.find_element_by_name('id_phone').send_keys('(404)555-1212')
self.browser.find_element_by_name('id_zip').send_keys("30306")
self.browser.find_element_by_name('submit').submit()
# this should return 1 more record
import time; time.sleep(10)
final_customer_count = Customer.query(ancestor=client.key).count()
self.assertNotEqual(orig_customer_count, final_customer_count)
assert(Customer.query(Customer.name == "Kallie Wheelock").get())
# Delete the Customer record
Customer.query(Customer.name =="Kallie Wheelock").delete()
你想测试什么 如果您尝试测试保存实体的代码,那么您可以编写一个简单的单元测试:saveentity,检查它是否已保存 如果您试图测试客户机代码,那么引入延迟会打破这种测试的想法。无法保证最终一致性的上限。您的UI代码应该能够处理任何时间延迟-从零到至少几秒钟
例如,如果实体的数量对于用户工作流程的延续很重要,那么大多数应用程序都会阻止UI(例如,显示某种进度条或微调器),直到调用成功完成。如果等待保存此实体不是用户工作流程的一部分,则无需在Selenium中对其进行测试-同样,您可以编写一个简单的单元测试。您要测试什么 如果您尝试测试保存实体的代码,那么您可以编写一个简单的单元测试:saveentity,检查它是否已保存 如果您试图测试客户机代码,那么引入延迟会打破这种测试的想法。无法保证最终一致性的上限。您的UI代码应该能够处理任何时间延迟-从零到至少几秒钟
例如,如果实体的数量对于用户工作流程的延续很重要,那么大多数应用程序都会阻止UI(例如,显示某种进度条或微调器),直到调用成功完成。如果等待保存此实体不是用户工作流程的一部分,则无需在Selenium中对其进行测试-同样,您可以编写一个简单的单元测试。您要测试什么 如果您尝试测试保存实体的代码,那么您可以编写一个简单的单元测试:saveentity,检查它是否已保存 如果您试图测试客户机代码,那么引入延迟会打破这种测试的想法。无法保证最终一致性的上限。您的UI代码应该能够处理任何时间延迟-从零到至少几秒钟
例如,如果实体的数量对于用户工作流程的延续很重要,那么大多数应用程序都会阻止UI(例如,显示某种进度条或微调器),直到调用成功完成。如果等待保存此实体不是用户工作流程的一部分,则无需在Selenium中对其进行测试-同样,您可以编写一个简单的单元测试。您要测试什么 如果您尝试测试保存实体的代码,那么您可以编写一个简单的单元测试:saveentity,检查它是否已保存 如果您试图测试客户机代码,那么引入延迟会打破这种测试的想法。无法保证最终一致性的上限。您的UI代码应该能够处理任何时间延迟-从零到至少几秒钟
例如,如果实体的数量对于用户工作流程的延续很重要,那么大多数应用程序都会阻止UI(例如,显示某种进度条或微调器),直到调用成功完成。如果等待保存此实体不是用户工作流程的一部分,则无需在Selenium中对其进行测试-同样,您可以编写一个简单的单元测试。我认为问题在于您的测试设置,而不是最终的一致性 数据存储有不同的实例,您需要确保使用了正确的实例:
import subprocess, time, os, unittest, shlex
from google.appengine.ext import db, testbed
from google.appengine.api import apiproxy_stub, apiproxy_stub_map
from selenium import webdriver
class SeleniumTest(unittest.TestCase):
def setUp(self):
# Start the dev server
cmd = "/.../bin/dev_appserver.py /.../app.yaml --storage_path /tmp/datastore --clear_datastore --skip_sdk_update_check"
self.dev_appserver = subprocess.Popen(shlex.split(cmd),
stdout=subprocess.PIPE)
time.sleep(2) # Important, let dev_appserver start up
self.testbed = testbed.Testbed()
self.testbed.setup_env(app_id="dev~myapp")
self.testbed.activate()
self.testbed.init_app_identity_stub()
self.testbed.init_datastore_v3_stub(
datastore_file="/tmp/datastore/datastore.db", use_sqlite=True)
self.testbed.init_taskqueue_stub()
self.testbed.init_memcache_stub()
self.testbed.init_blobstore_stub()
self.testbed.init_user_stub()
self.testbed.init_mail_stub()
self.testbed.init_urlfetch_stub()
self.taskqueue_stub = apiproxy_stub_map.apiproxy.GetStub('taskqueue')
self.mail_stub = apiproxy_stub_map.apiproxy.GetStub('mail')
self.datastore_stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')
# Start the headless browser for Selenium tests
self.driver = webdriver.Firefox()
def tearDown(self):
self.testbed.deactivate()
self.driver.quit()
self.dev_appserver.terminate()
我认为问题在于您的测试设置,而不是最终的一致性 数据存储有不同的实例,您需要确保使用了正确的实例:
import subprocess, time, os, unittest, shlex
from google.appengine.ext import db, testbed
from google.appengine.api import apiproxy_stub, apiproxy_stub_map
from selenium import webdriver
class SeleniumTest(unittest.TestCase):
def setUp(self):
# Start the dev server
cmd = "/.../bin/dev_appserver.py /.../app.yaml --storage_path /tmp/datastore --clear_datastore --skip_sdk_update_check"
self.dev_appserver = subprocess.Popen(shlex.split(cmd),
stdout=subprocess.PIPE)
time.sleep(2) # Important, let dev_appserver start up
self.testbed = testbed.Testbed()
self.testbed.setup_env(app_id="dev~myapp")
self.testbed.activate()
self.testbed.init_app_identity_stub()
self.testbed.init_datastore_v3_stub(
datastore_file="/tmp/datastore/datastore.db", use_sqlite=True)
self.testbed.init_taskqueue_stub()
self.testbed.init_memcache_stub()
self.testbed.init_blobstore_stub()
self.testbed.init_user_stub()
self.testbed.init_mail_stub()
self.testbed.init_urlfetch_stub()
self.taskqueue_stub = apiproxy_stub_map.apiproxy.GetStub('taskqueue')
self.mail_stub = apiproxy_stub_map.apiproxy.GetStub('mail')
self.datastore_stub = apiproxy_stub_map.apiproxy.GetStub('datastore_v3')
# Start the headless browser for Selenium tests
self.driver = webdriver.Firefox()
def tearDown(self):
self.testbed.deactivate()
self.driver.quit()
self.dev_appserver.terminate()
我认为问题在于您的测试设置,而不是最终的一致性 数据存储有不同的实例,您需要确保