私が Django アプリケーション用に作成したテストは、SQLite を使用した初期開発中に完全に機能しています。展開する準備ができたので、MySQL サーバーをセットアップしました (これが展開先になります) が、テストの一部が失敗しています。
最後に、機能を手動でテストしても、失敗するテストは失敗しません。
何が起こっているのでしょうか?
私は何も変わったことをしていません。すべてのビューがデータベースの悪ふざけを行い、応答を返します。タイミングに関連するものは何もありません (スレッドなどはありません)。
テストはすべて django.test.TestCase から継承されており、フィクスチャは使用していません。
失敗するテストの例を次に示します。
class BaseTest(TestCase):
def setUp(self):
super(BaseTest, self).setUp()
self.userCreds = dict(username='test', password='a')
# Create an admin user
admin = models.User.objects.create_superuser(
email='', username='admin', password='a')
# Create a user and grant them a licence
user = models.User.objects.create_user(
email='some@address.com', first_name="Mister",
last_name="Testy", **self.userCreds)
profile = models.getProfileFor(user)
node = profile.createNode(
'12345', 'acomputer', 'auser',
'user@email.com', '0456 987 123')
self.node = node
class TestClientUIViews(BaseTest):
def test_toggleActive(self):
url = reverse('toggleActive') + '?nodeId=%s' % self.node.nodeId
self.assertFalse(self.node.active)
# This should fail because only authenticated users can toggle a node active
resp = self.client.get(url)
self.assertEqual(resp.status_code, 403)
self.assertFalse(self.node.active)
# Login and make sure visiting the url toggles the active state
self.client.login(**self.userCreds)
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
self.assertTrue(self.node.active)
resp = self.client.get(url)
self.assertEqual(resp.status_code, 200)
self.assertFalse(self.node.active)
モデルは次のようになります。
class Node(models.Model):
@property
def active(self):
'''
Activation state gets explictly tracked in its own table but is
exposed as a property for the sake of convenience
'''
activations = NodeActivation.objects \
.filter(node=self) \
.order_by('-datetime')
try:
return activations[0].active
except IndexError:
return False
@active.setter
def active(self, state):
if self.active != state:
NodeActivation.objects.create(node=self, active=state)
class NodeActivation(models.Model):
node = models.ForeignKey("Node")
datetime = models.DateTimeField(default=datetimeM.datetime.now)
active = models.BooleanField(default=False)
私のローカル MySQL は 5.5.19 (InnoDB を使用) ですが、5.1.56 を使用しているデプロイメント サーバーでも同じエラーが発生します。ストレージ エンジンに関係なく、テストは失敗します。
冒頭で述べたように、SQLite データベースを使用するように切り替えると、すべてのテストが合格に戻ります。