Con py.test, la base de datos no se restablece después de LiveServerTestCase

Tengo varias pruebas de Django y normalmente las ejecuto con py.test. Recientemente agregué un nuevo caso de prueba en un nuevo archivo test_selenium.py . Este caso de prueba utiliza las clases LiveServerTestCase y StaticLiveServerTestCase (que es la primera para mí, normalmente solo uso TestCase ).

Agregar este nuevo lote de pruebas en este nuevo archivo ha provocado que las pruebas posteriores empiecen a fallar en py.test (cuando antes pasaban todas). Parece que la base de datos no se está “restableciendo” después de LiveServerTestCase en py.test. Puedo decirlo debido a la incrementación de los valores pk de mi modelo.

Cuando ejecuto estas pruebas utilizando el corredor de pruebas Django, todas pasan y las pk se restablecen en las pruebas posteriores; en el corredor de prueba py.test, los pk se incrementan en las pruebas posteriores una LiveServerTestCase se ejecuta el LiveServerTestCase . Entonces, si tengo un código fijo en mi prueba para crear un objeto y recuperarlo según el pk espero que falle porque las bases de datos son diferentes entre Django y py.test.

¿Alguna idea de por qué esto podría ser y cómo solucionarlo?

Nueva prueba de prueba que causa el comportamiento de DB:

 from django.contrib.staticfiles.testing import StaticLiveServerTestCase from selenium import webdriver from selenium.webdriver.support.ui import WebDriverWait from selenium.webdriver.support import expected_conditions as EC from selenium.webdriver.common.by import By class UpdateCountSelenium(StaticLiveServerTestCase): def setUp(self): self.selenium = webdriver.Firefox() self.delay = 3 def tearDown(self): self.selenium.quit() def test_ajax_hit(self): self.selenium.get("%s%s" % (self.live_server_url, '/1/')) # waits for javascript to load and tests the ajax view wait = WebDriverWait(self.selenium, 3) response = wait.until(EC.text_to_be_present_in_element((By.ID, 'counted-value'), 'true')) self.assertTrue(response) 

Un LiveServerTestCase y su subclase StaticLiveServerTestCase heredan de TransactionTestCase que difiere de TestCase en la forma en que restablece el DB en el caso de prueba tearDown . Aquí está la cita de la documentación antes mencionada:

La clase TestCase de Django (que se describe a continuación) utiliza las instalaciones de transacciones de la base de datos para acelerar el proceso de restablecimiento de la base de datos a un estado conocido al comienzo de cada prueba. Sin embargo, una consecuencia de esto es que algunos comportamientos de base de datos no se pueden probar dentro de una clase de Django TestCase . Por ejemplo, no puede probar que un bloque de código se está ejecutando dentro de una transacción, como se requiere cuando se usa select_for_update () . En esos casos, debe utilizar TransactionTestCase .

TransactionTestCase y TestCase son idénticos, excepto por la manera en que la base de datos se restablece a un estado conocido y la capacidad del código de prueba para probar los efectos de confirmación y reversión:

  • Un TransactionTestCase restablece la base de datos después de que se ejecuta la prueba truncando todas las tablas. Un TransactionTestCase puede llamar a commit y rollback y observar los efectos de estas llamadas en la base de datos.

  • Un TestCase , por otro lado, no trunca las tablas después de una prueba. En su lugar, incluye el código de prueba en una transacción de base de datos que se revierte al final de la prueba. Esto garantiza que la reversión al final de la prueba restaura la base de datos a su estado inicial.

Como mencionaste, ves el contador de PK retenido. Esto se debe a que truncar tablas significa eliminar todas las filas, pero esto generalmente no significa que el contador PK se reinicie.

Supongo que le importa esto porque está utilizando objetos de afirmación al especificar un PK (por ejemplo, assert YourModel.objects.filter(pk=1).exists() .

En su lugar, sugiero que en sus pruebas, afirme la existencia de objetos X (por ejemplo, assert YourModel.objects.count() == 1 , o incluso afirme los objetos específicos que espera que existan) y luego use estos objetos en su prueba como normalmente lo harías