Tes unit Django saya membutuhkan waktu lama untuk dijalankan, jadi saya mencari cara untuk mempercepatnya. Saya sedang mempertimbangkan untuk menginstal SSD , tetapi saya tahu itu memiliki kelemahan juga. Tentu saja, ada hal-hal yang bisa saya lakukan dengan kode saya, tetapi saya sedang mencari perbaikan struktural. Bahkan menjalankan satu tes lambat karena database perlu dibangun kembali / dimigrasi ke selatan setiap waktu. Jadi, inilah ideku ...
Karena saya tahu database pengujian akan selalu sangat kecil, mengapa saya tidak bisa hanya mengkonfigurasi sistem untuk selalu menjaga seluruh database pengujian dalam RAM? Jangan pernah menyentuh disk sama sekali. Bagaimana cara mengkonfigurasi ini di Django? Saya lebih suka tetap menggunakan MySQL karena itulah yang saya gunakan dalam produksi, tetapi jika SQLite 3 atau yang lainnya membuat ini mudah, saya akan melakukannya.
Apakah SQLite atau MySQL memiliki opsi untuk berjalan sepenuhnya dalam memori? Seharusnya dimungkinkan untuk mengkonfigurasi disk RAM dan kemudian mengkonfigurasi database tes untuk menyimpan datanya di sana, tapi saya tidak yakin bagaimana cara memberitahu Django / MySQL untuk menggunakan direktori data yang berbeda untuk database tertentu, terutama karena itu terus terhapus. dan diciptakan kembali setiap menjalankan. (Saya menggunakan Mac FWIW.)
sumber
"test" in sys.argv
; mungkin memicu ketika Anda tidak menginginkannya, misalnyamanage.py collectstatic -i test
.sys.argv[1] == "test"
adalah kondisi yang lebih tepat yang seharusnya tidak memiliki masalah itu.Saya biasanya membuat file pengaturan terpisah untuk pengujian dan menggunakannya dalam perintah uji misalnya
Ini memiliki dua manfaat:
Anda tidak perlu memeriksa
test
atau kata ajaib seperti itu di sys.argv,test_settings.py
bisa sajaAtau Anda dapat mengubah lebih lanjut untuk kebutuhan Anda, memisahkan pengaturan pengujian dengan bersih dari pengaturan produksi.
Manfaat lain adalah Anda dapat menjalankan pengujian dengan mesin basis data produksi alih-alih sqlite3 menghindari bug yang halus, jadi sambil mengembangkan penggunaan
dan sebelum melakukan kode dijalankan sekali
hanya untuk memastikan bahwa semua tes benar-benar lulus.
sumber
MySQL mendukung mesin penyimpanan yang disebut "MEMORY", yang dapat Anda konfigurasi di konfigurasi database Anda (
settings.py
) seperti:Perhatikan bahwa mesin penyimpanan MEMORY tidak mendukung kolom blob / teks, jadi jika Anda menggunakan
django.db.models.TextField
ini tidak akan bekerja untuk Anda.sumber
Saya tidak bisa menjawab pertanyaan utama Anda, tetapi ada beberapa hal yang dapat Anda lakukan untuk mempercepatnya.
Pertama, pastikan bahwa database MySQL Anda diatur untuk menggunakan InnoDB. Kemudian dapat menggunakan transaksi untuk mengembalikan keadaan db sebelum setiap tes, yang menurut pengalaman saya telah menyebabkan peningkatan besar-besaran. Anda dapat melewatkan perintah init database di settings.py Anda (sintaks Django 1.2):
Kedua, Anda tidak perlu menjalankan migrasi Selatan setiap kali. Diatur
SOUTH_TESTS_MIGRATE = False
dalam settings.py Anda dan basis data akan dibuat dengan syncdb biasa, yang akan jauh lebih cepat daripada menjalankan semua migrasi historis.sumber
369 tests in 498.704s
menjadi369 tests in 41.334s
. Ini lebih dari 10 kali lebih cepat!--keep
untuk mempertahankan database dan tidak memerlukan set lengkap migrasi Anda untuk diterapkan kembali pada setiap percobaan. Migrasi baru masih akan berjalan. Jika Anda sering berpindah antar cabang, mudah untuk masuk ke kondisi tidak konsisten (Anda dapat mengembalikan migrasi baru sebelum Anda beralih dengan mengubah database ke database pengujian dan menjalankannyamigrate
, tetapi ini sedikit menyebalkan).Anda dapat melakukan tweaker ganda:
Saya menggunakan kedua trik dan saya cukup senang.
Cara mengaturnya untuk MySQL di Ubuntu:
Hati-hati, ini hanya untuk pengujian, setelah reboot database Anda dari memori hilang!
sumber
Pendekatan lain: minta instance MySQL lain berjalan di tempfs yang menggunakan RAM Disk. Petunjuk dalam posting blog ini: Mempercepat MySQL untuk pengujian di Django .
Keuntungan:
sumber
Memperluas jawaban Anurag, saya menyederhanakan proses dengan membuat test_settings yang sama dan menambahkan berikut ini ke manage.py
tampaknya lebih bersih karena sys sudah diimpor dan manage.py hanya digunakan melalui baris perintah, jadi tidak perlu mengacaukan pengaturan
sumber
"test" in sys.argv
; mungkin memicu ketika Anda tidak menginginkannya, misalnyamanage.py collectstatic -i test
.sys.argv[1] == "test"
adalah kondisi yang lebih tepat yang seharusnya tidak memiliki masalah itu../manage.py
tanpa argumen (mis. untuk melihat plugin mana yang tersedia, sama seperti--help
)len(sys.argv) > 1 and sys.argv[1] == "test"
Gunakan di bawah ini di
setting.py
sumber