我使用Django 1.4,Selenium 2.53.1和Chrome Webdriver 2.21作为我的测试webdriver来测试我的Django应用程序。
我这样初始化我的课程:
class SeleniumTest(LiveServerTestCase):
@classmethod
def setUpClass(cls):
cls.display = Display(visible=0, size=(800, 600))
cls.display.start()
cls.driver = webdriver.Chrome()
cls.driver.set_page_load_timeout(15)
cls.driver.maximize_window()
super(SeleniumTest, cls).setUpClass()
def setUp(self):
settings.SESSION_ENGINE = 'django.contrib.sessions.backends.db'
engine = import_module(settings.SESSION_ENGINE)
self.sessionStore = engine.SessionStore()
self.sessionStore.save()
username = 'hello'
password = 'hello'
self.cad_user, created = User.objects.get_or_create(username=username, email='hello@hello.com')
self.cad_user.set_password(password)
self.cad_user.save()
try:
self.get_url('login')
if self.driver.title == 'Login':
self.driver.find_element_by_id('id_username').send_keys(username)
self.driver.find_element_by_id('id_password').send_keys(password)
self.driver.find_element_by_css_selector('input[type="submit"]').click()
我的测试的一个例子如下。它会测试一个下拉菜单,其中包含多个级别,这些级别在您将鼠标移到它们之后出现并检查它们是否转到正确的链接
def dropdown_check(self, header_ids, choice_id, title):
choice = self.driver.find_element_by_id(choice_id)
mouse = webdriver.ActionChains(self.driver)
for header_id in header_ids:
header_element = self.driver.find_element_by_id(header_id)
WebDriverWait(self.driver, 1).until(EC.element_to_be_clickable((By.ID, header_id)))
mouse.move_to_element(header_element)
mouse.perform()
WebDriverWait(self.driver, 1).until(EC.element_to_be_clickable((By.ID, choice_id)))
choice.click()
self.assertEquals(self.driver.title, title)
def test_my_status_navigation(self):
self.dropdown_check(['menubar_my_status'], 'menubar_my_status', 'User Status')
我尝试过这些事情:
鉴于此,整套8个测试需要超过300秒,我不知道为什么。我确定Webdriver的加载需要一些时间,但在每次单独测试结束后,我都可以看到Webdriver只是坐在那里什么都不做。
答案 0 :(得分:2)
最大的问题是LiveServerTestCase
是Django项目中所有测试用例中最慢的。它继承自TransactionTestCase
TransactionTestCase继承自SimpleTestCase以添加一些 特定于数据库的功能:
在每次测试开始时将数据库重置为已知状态 轻松测试和使用ORM。
和
Django的TestCase类是一个比较常用的子类 TransactionTestCase,它使用数据库事务工具 加快将数据库重置为已知状态的过程 每个测试的开始。
因此,每个测试都会导致数据库完全重置,这非常慢。一种解决方案是使用-k或--keep选项。
./manage.py test -k myapp
这将从测试执行时间开始至少减少100秒。
还有另一种解决方案无法在所有条件下应用,因为TestCase不能用于Selenium测试。但是,您可以编写独立的selenium测试,连接到开发服务器以加快某些测试。在这种情况下,您可以使用python中的unittest.TestCase
而不是django.test.testcases.TestCase
。这听起来完全令人困惑所以让我举个例子!
from unittest import TestCase
from selenium import webdriver
class SeleniumTest(TestCase):
def setUp(self):
# usual code to setup drivers etc
def testSomething(self):
self.driver.get('localhost:8000/somepage')
# now you are connecting directly to the development server.
# this approach is not suitable for all requirements but
# very fast compared to using a LiveServerTestCase
最后但并非最不重要:通常你根本不需要LiveServerTestCase或selenium测试。使用django test client
更快更容易答案 1 :(得分:0)
我已经将它缩小到与Django有关的事情以及它与数据库的交互方式,因为我使用connectionFactory
和 AbandonedConfig cfg = new AbandonedConfig ();
cfg.setLogAbandoned (true);
cfg.setRemoveAbandonedTimeout (5);
cfg.setRemoveAbandoned (true);
GenericObjectPool connectionPool = new AbandonedObjectPool(null, cfg);
connectionPool.setTestWhileIdle (true);
connectionPool.setTestOnBorrow (true);
connectionPool.setTestOnReturn (true);
connectionPool.setMaxActive (5);
connectionPool.setMaxWait (5000);
ConnectionFactory connectionFactory = new DriverManagerConnectionFactory("jdbc:mysql://localhost:3306/Test?user=testuser&password=password",null);
PoolableConnectionFactory poolableConnectionFactory = new PoolableConnectionFactory(connectionFactory,connectionPool,null,null,false,true, cfg);
poolableConnectionFactory.setValidationQuery ("SELECT 1");
Class.forName("org.apache.commons.dbcp.PoolingDriver");
PoolingDriver driver = (PoolingDriver) DriverManager.getDriver("jdbc:apache:commons:dbcp:");
driver.registerPool("test_pool",connectionPool);
//This throws the error
Connection conn = DriverManager.getConnection( "jdbc:apache:commons:dbcp:" );
//This does too
//Connection conn = DriverManager.getConnection( "jdbc:apache:commons:dbcp:Test" );
以及我的测试方法运行:
setup
并且整体时间不会改变,将数据库更改为sqlite3会显着减少整个测试时间的某些错误。