1

最近、Djangoプロジェクトの設定を変更して、PostgreSQLの代わりにテストを実行するときにSQLite3を使用するようにしました。これにより、テストがより高速に実行されます。ただし、それを実行すると、ユーザー名が30文字を超えるユーザーを作成しようとすると、Djangoがエラーをスローすることを確認するネガティブ単体テストの1つが失敗し始めました。この時まで、テストは常に合格していました。

PostgreSQLを使用して次のテストを実行すると、例外(具体的にはDatabaseError)が発生し、テストに合格します。ただし、代わりにSQLite3を使用すると、例外は発生せず、テストは失敗します。SQLite3 auth_userスキーマを再確認し、ユーザー名がvarchar(30)フィールドであることを確認しました。他の誰かがこれを経験しましたか?ありがとう。

from django.test import TestCase
from django.contrib.auth.models import User

class SimpleTest(TestCase):
    def test_simple(self):
        exception_raised = True  # Exception should be raised since username > 30 chars
        try:
            user = User.objects.create_user(username='testusertestusertestusertestuser')
        except Exception as e:
            exception_raised = False
        assert not exception_raised, "Exception wasn't raised"
4

2 に答える 2

1

ズーコの答えに加えて、私はあなたのユニットテストが正しいことをしていないかもしれないと争うでしょう。

モデルの検証は保存される前に行われるというのはよくある誤解のようです。モデル検証のドキュメントを参照してください。

あなたがしていることはmax_length、検証関数を経ることなく、モデルフィールドへのパラメータが尊重されることを期待しています。を使用するModelFormsと、フォームによってモデル検証が呼び出され、が取得されますValidationError

is_blankタイプのオプションなどの他の制約にも同じことが当てはまりCharFieldます。私の知る限り、フィールドが空白かどうかをチェックするためにデータベースレベルで適用できる利用可能な制約がないため、この検証はPythonランドでのみ発生します。

この問題に関連するStackOverflowには他にも多くの質問があり、すべての状況で検証を強制する方法を説明しています。たとえば、この回答

または、単体テストでfull_clean()インスタンスメソッドを呼び出して、すべての検証制約が満たされていることを確認します。

于 2013-02-01T01:51:04.263 に答える
0

この理由は、sqlite3がすべてのvarcharデータ型を内部でテキストデータ型に変換するためだと思います。これが、DBMSが制限を超える値をキャッチしない理由です。ドキュメントはこの点で少し不明確ですが、ドキュメントの前とドキュメントからこの問題に遭遇しました。それが私が思いついた最良の答えでした。だから基本的に、

CREATE TABLE A(name varchar(30))

最終的には次のものと同じになります。

CREATE TABLE A(name text)

ここのドキュメントをチェックしてください(セクション2.2):http ://www.sqlite.org/datatype3.html

これがDBMSの機能にすぎないことを確認するために実行できるテスト:

sqlite> create table A(name varchar(2));
sqlite> insert into A values("hello world");
sqlite> select * from A;
hello world

ご覧のとおり、エラーや切り捨てはありません。

お役に立てば幸いです。

于 2013-01-31T23:32:06.493 に答える