Pertanyaan Perintah pengujian tidak diuji


Bagaimana cara memastikan pesanan metode unittest? Apakah awalan alfabet atau numerik sesuai dengan cara yang benar?

class TestFoo(TestCase):
    def test_1(self):
        ...
    def test_2(self):
        ...

atau

class TestFoo(TestCase):
    def test_a(self):
        ...
    def test_b(self):
        ...

31
2017-11-04 09:32


asal


Jawaban:


Anda dapat menonaktifkannya dengan mengatur sortTestMethodsUsing to None: http://docs.python.org/2/library/unittest.html#unittest.TestLoader.sortTestMethodsUsing

Untuk unittest murni, kalian benar; tetapi untuk tes komponen dan tes integrasi ... Saya tidak setuju bahwa Anda tidak akan berasumsi tentang negara. Bagaimana jika Anda menguji negara. Sebagai contoh, tes Anda memvalidasi bahwa layanan otomatis dimulai setelah instalasi. Jika dalam pengaturan Anda, Anda memulai layanan, kemudian lakukan pernyataan, maka Anda tidak lagi menguji keadaan tetapi Anda menguji fungsionalitas "mulai layanan".

Contoh lain adalah ketika setup Anda membutuhkan waktu yang lama atau membutuhkan banyak ruang dan itu menjadi tidak praktis untuk menjalankan setup secara berkala.

Banyak pengembang cenderung menggunakan kerangka "unittest" untuk pengujian komponen ... jadi berhentilah dan tanyakan pada diri Anda sendiri, apakah saya melakukan pengujian tanpa alat atau komponen.


50
2018-03-11 06:15



Tidak ada alasan yang diberikan bahwa Anda tidak dapat membangun apa yang telah dilakukan dalam tes sebelumnya atau harus membangun kembali semuanya dari awal untuk ujian berikutnya. Setidaknya tidak ada alasan biasanya ditawarkan tetapi orang hanya dengan percaya diri mengatakan "Anda tidak seharusnya". Itu tidak membantu.

Secara umum saya lelah membaca terlalu banyak jawaban di sini yang mengatakan pada dasarnya "Anda seharusnya tidak melakukan itu" daripada memberikan informasi tentang cara terbaik melakukannya jika dalam penilaian penanya ada alasan bagus untuk melakukannya. Jika saya ingin pendapat seseorang tentang apakah saya harus melakukan sesuatu maka saya akan meminta pendapat tentang apakah melakukan itu adalah ide yang baik.

Itu keluar dari jalan, jika Anda membaca mengatakan loadTestsFromTestCase dan apa yang disebutnya itu akhirnya memindai metode dengan beberapa pola nama dalam urutan apa pun yang mereka temui dalam kamus metode kelas, jadi pada dasarnya dalam urutan kunci. Ia mengambil informasi ini dan membuat testsuite untuk memetakannya ke kelas TestCase. Memberikannya bukan daftar yang dipesan seperti yang Anda inginkan adalah salah satu cara untuk melakukan ini. Saya tidak begitu yakin cara yang paling efisien / terbersih untuk melakukannya tetapi ini berhasil.


60
2017-11-07 02:17



Mengapa Anda membutuhkan pesanan tes khusus? Tes harus diisolasi dan oleh karena itu harus memungkinkan untuk menjalankannya dalam urutan apa pun, atau bahkan secara paralel.

Jika Anda perlu menguji sesuatu seperti berhenti berlangganan pengguna, tes bisa membuat database baru dengan langganan tes dan kemudian mencoba untuk berhenti berlangganan. Skenario ini memiliki masalah tersendiri, tetapi pada akhirnya lebih baik daripada memiliki pengujian yang bergantung satu sama lain. (Perhatikan bahwa Anda dapat menghitung kode tes umum, sehingga Anda tidak perlu mengulang kode penyiapan DB atau membuat data pengujian membuat mual.)


13
2017-11-04 09:34



Jika Anda menggunakan 'hidung' dan Anda menulis kasus uji Anda sebagai fungsi (dan bukan sebagai metode dari beberapa kelas turunan TestCase) 'hidung' tidak bermain-main dengan pesanan, tetapi menggunakan urutan fungsi seperti yang didefinisikan dalam file. Agar memiliki metode assert_ * berguna tanpa perlu subclass TestCase saya biasanya menggunakan modul pengujian dari numpy. Contoh:

from numpy.testing import *

def test_aaa():
    assert_equal(1, 1)

def test_zzz():
    assert_equal(1, 1)

def test_bbb():
    assert_equal(1, 1)

Menjalankan itu dengan '' nosetest -vv '' memberi:

test_it.test_aaa ... ok
test_it.test_zzz ... ok
test_it.test_bbb ... ok
----------------------------------------------------------------------
Ran 3 tests in 0.050s
OK

Catatan untuk semua orang yang berpendapat bahwa tes unit tidak boleh dipesan: sementara benar bahwa tes unit harus diisolasi dan dapat berjalan sendiri, fungsi dan kelas Anda biasanya tidak independen. Mereka lebih suka membangun yang lain dari fungsi yang lebih sederhana / tingkat rendah ke fungsi yang lebih kompleks / tingkat tinggi. Ketika Anda mulai mengoptimalkan fungsi tingkat rendah dan mengacaukan (untuk bagian saya, saya sering melakukannya; jika tidak, Anda mungkin tidak perlu uji unit ;-) maka itu jauh lebih baik untuk mendiagnosis penyebabnya, ketika tes untuk fungsi sederhana datang lebih dulu, dan tes untuk fungsi yang bergantung pada fungsi-fungsi itu nantinya. Jika tes diurutkan berdasarkan abjad penyebab sebenarnya biasanya akan tenggelam di antara seratus pernyataan gagal, yang tidak ada karena fungsi yang diuji memiliki bug, tetapi karena fungsi tingkat rendahnya bergantung pada has.

Itulah mengapa saya ingin menguji unit saya sesuai cara yang saya tetapkan: tidak menggunakan status yang dibangun dalam pengujian awal di tes berikutnya, tetapi sebagai alat yang sangat membantu dalam mendiagnosis masalah.


12
2017-10-27 13:10



Jangan bergantung pada pesanan. Jika mereka menggunakan beberapa keadaan umum seperti filesystem atau database, maka Anda harus membuat setUp dan tearDown metode yang membuat lingkungan Anda menjadi negara yang dapat diuji, lalu bersihkan setelah tes dijalankan. Setiap tes harus mengasumsikan bahwa lingkungan seperti yang didefinisikan dalam setUp, dan seharusnya tidak membuat asumsi lebih lanjut.


9
2017-11-04 09:54



Saya setengah setuju dengan gagasan bahwa tes tidak dapat dipesan. Dalam beberapa kasus itu membantu (lebih mudah terkutuk!) Untuk memilikinya secara berurutan ... setelah semua itulah alasan untuk 'unit' di UnitTest.

Yang mengatakan satu alternatif adalah menggunakan objek tiruan untuk mengolok-olok dan menambal item yang harus dijalankan sebelum kode spesifik yang diuji. Anda juga bisa meletakkan fungsi boneka di sana untuk monyet menambal kode Anda. Untuk info lebih lanjut periksa Mock, yang merupakan bagian dari pustaka standar sekarang. Mengejek

Berikut beberapa video YouTube jika Anda belum pernah menggunakan Mock sebelumnya.

Video 1

Video 2

Video 3

Lebih penting lagi, coba gunakan metode kelas untuk menyusun kode Anda, lalu tempatkan semua metode kelas dalam satu metode tes utama.

import unittest
import sqlite3

class MyOrderedTest(unittest.TestCase):

    @classmethod
    def setUpClass(cls):
        cls.create_db()
        cls.setup_draft()
        cls.draft_one()
        cls.draft_two()
        cls.draft_three()

    @classmethod
    def create_db(cls):
        cls.conn = sqlite3.connect(":memory:")

    @classmethod
    def setup_draft(cls):
        cls.conn.execute("CREATE TABLE players ('draftid' INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, 'first', 'last')")

    @classmethod
    def draft_one(cls):
        player = ("Hakeem", "Olajuwon")
        cls.conn.execute("INSERT INTO players (first, last) VALUES (?, ?)", player)

    @classmethod
    def draft_two(cls):
        player = ("Sam", "Bowie")
        cls.conn.execute("INSERT INTO players (first, last) VALUES (?, ?)", player)

    @classmethod
    def draft_three(cls):
        player = ("Michael", "Jordan")
        cls.conn.execute("INSERT INTO players (first, last) VALUES (?, ?)", player)

    def test_unordered_one(self):
        cur = self.conn.execute("SELECT * from players")
        draft = [(1, u'Hakeem', u'Olajuwon'), (2, u'Sam', u'Bowie'), (3, u'Michael', u'Jordan')]
        query = cur.fetchall()
        print query
        self.assertListEqual(query, draft)

    def test_unordered_two(self):
        cur = self.conn.execute("SELECT first, last FROM players WHERE draftid=3")
        result = cur.fetchone()
        third = " ".join(result)
        print third
        self.assertEqual(third, "Michael Jordan")

7
2017-08-16 05:56



Ada sejumlah alasan untuk memprioritaskan pengujian, tidak sedikit yang merupakan produktivitas, yang menjadi tujuan JUnit Max. Terkadang sangat membantu untuk menyimpan tes yang sangat lambat dalam modul mereka sendiri sehingga Anda dapat memperoleh umpan balik cepat dari tes-tes yang tidak menderita dari ketergantungan berat yang sama. Memesan juga membantu dalam melacak kegagalan dari tes yang tidak sepenuhnya mandiri.


6
2018-05-02 19:15



Ok, mungkin sedikit terlambat, tapi bagaimanapun ...

Kamu harus mencobanya belalai Perpustakaan. Ini akan memungkinkan Anda untuk melakukan tes pesanan serta mengatur setiap dependensi uji. Saya menggunakannya dan perpustakaan ini benar-benar mengagumkan.

Misalnya, jika test case #1 dari module A harus bergantung pada test case #3 dari module B kamu BISA mengatur perilaku ini menggunakan pustaka.


6
2018-02-07 14:02



Ada skenario di mana pesanan dapat menjadi penting dan di mana setUp dan Teardown masuk sebagai terbatas. Hanya ada satu metode setUp dan teardown, yang logis, tetapi Anda hanya dapat menyimpan begitu banyak informasi di dalamnya hingga tidak jelas apa yang sebenarnya terjadi.

Ikuti tes integrasi ini sebagai contoh:

Anda sedang menulis tes untuk melihat apakah formulir pendaftaran dan formulir login berfungsi dengan benar. Dalam kasus semacam itu urutannya penting, karena Anda tidak dapat masuk tanpa akun yang sudah ada.   Lebih penting lagi urutan tes Anda mewakili beberapa jenis interaksi pengguna. Di mana setiap tes mungkin mewakili langkah dalam keseluruhan proses atau alur yang Anda uji.

Membagi kode Anda dalam potongan-potongan logis memiliki beberapa keuntungan.

Mungkin bukan solusi terbaik, tetapi saya sering menggunakan satu metode yang memulai tes yang sebenarnya.

def test_registration_login_flow(self):
    _test_registration_flow()
    _test_login_flow()

4
2018-05-14 22:09



http://docs.python.org/library/unittest.html

Perhatikan bahwa urutan di mana berbagai uji kasus akan dijalankan ditentukan dengan menyortir nama fungsi pengujian sehubungan dengan pemesanan string bawaan.

Jika Anda perlu mengatur pesanan secara eksplisit, gunakan tes monolitik.

class Monolithic(TestCase):
  def step1(self):
      ...

  def step2(self):
      ...

  def steps(self):
    for name in sorted(dir(self)):
      if name.startswith("step"):
        yield name, getattr(self, name) 

  def test_steps(self):
    for name, step in self.steps():
      try:
        step()
      except Exception as e:
        self.fail("{} failed ({}: {})".format(step, type(e), e)

Periksa pos untuk detailnya.


3
2017-08-26 13:48