Python mock meningkatkan pengecualian sekali

Lebih sering daripada tidak, perangkat lunak yang kami tulis berinteraksi langsung dengan apa yang kami beri label sebagai layanan "kotor". Dalam istilah awam. layanan yang sangat penting untuk aplikasi kita, tetapi interaksinya memiliki efek samping yang disengaja tetapi tidak diinginkan—yaitu, tidak diinginkan dalam konteks uji coba otonom. Sebagai contoh. mungkin kami sedang menulis aplikasi sosial dan ingin menguji 'fitur Posting ke Facebook' baru kami, tetapi tidak ingin benar-benar memposting ke Facebook setiap kali kami menjalankan rangkaian pengujian kami. Pustaka

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
_7 Python menyertakan subpaket bernama
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
8—atau jika Anda mendeklarasikannya sebagai dependensi, cukup
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9—yang menyediakan sarana yang sangat kuat dan berguna untuk mengejek dan mematikan efek samping yang tidak diinginkan ini

Oleh

Naftuli Kay

Dari membangun server TCP khusus hingga aplikasi keuangan berskala besar, pengalaman Naftuli yang luas membuatnya menjadi dev dan sysadmin kelas atas

BAGIKAN

BAGIKAN

Cara Menjalankan Tes Unit dengan Python Tanpa Menguji Kesabaran Anda

Lebih sering daripada tidak, perangkat lunak yang kami tulis berinteraksi langsung dengan apa yang kami beri label sebagai layanan "kotor". Dalam istilah awam. layanan yang sangat penting untuk aplikasi kita, tetapi interaksinya memiliki efek samping yang disengaja tetapi tidak diinginkan—yaitu, tidak diinginkan dalam konteks uji coba otonom

Sebagai contoh. mungkin kami sedang menulis aplikasi sosial dan ingin menguji 'fitur Posting ke Facebook' baru kami, tetapi tidak ingin benar-benar memposting ke Facebook setiap kali kami menjalankan rangkaian pengujian kami

Pustaka

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
_7 Python menyertakan subpaket bernama
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
8—atau jika Anda mendeklarasikannya sebagai dependensi, cukup
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9—yang menyediakan sarana yang sangat kuat dan berguna untuk mengejek dan mematikan efek samping yang tidak diinginkan ini

mocking and unit tests in python unittest library

Catatan.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
_9 baru saja disertakan dalam pustaka standar pada Python 3. 3;

Panggilan Sistem vs. Mengejek Python

Untuk memberi Anda contoh lain, dan yang akan kami jalankan untuk sisa artikel ini, pertimbangkan panggilan sistem. Tidak sulit untuk melihat bahwa ini adalah kandidat utama untuk diolok-olok. apakah Anda sedang menulis skrip untuk mengeluarkan drive CD, server web yang menghapus file cache kuno dari

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
4, atau server soket yang mengikat ke port TCP, panggilan ini semua menampilkan efek samping yang tidak diinginkan dalam konteks unit Anda-

Sebagai pengembang, Anda lebih peduli bahwa pustaka Anda berhasil memanggil fungsi sistem untuk mengeluarkan CD daripada membuat baki CD Anda terbuka setiap kali pengujian dijalankan

Sebagai pengembang, Anda lebih peduli bahwa pustaka Anda berhasil memanggil fungsi sistem untuk mengeluarkan CD (dengan argumen yang benar, dll. ) daripada benar-benar mengalami baki CD Anda terbuka setiap kali tes dijalankan. (Atau lebih buruk lagi, berkali-kali, karena beberapa pengujian mereferensikan kode eject selama menjalankan pengujian unit tunggal. )

Demikian pula, menjaga unit-test Anda tetap efisien dan berkinerja berarti menjaga sebanyak mungkin "kode lambat" dari proses pengujian otomatis, yaitu sistem file dan akses jaringan.

Untuk contoh pertama kami, kami akan memfaktorkan ulang test case Python standar dari bentuk aslinya menjadi bentuk menggunakan

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9. Kami akan mendemonstrasikan bagaimana menulis kasus pengujian dengan tiruan akan membuat pengujian kami lebih cerdas, lebih cepat, dan dapat mengungkapkan lebih banyak tentang cara kerja perangkat lunak

Fungsi Hapus Sederhana

Kita semua perlu menghapus file dari sistem file kita dari waktu ke waktu, jadi mari kita menulis sebuah fungsi dengan Python yang akan membuat skrip kita lebih mudah melakukannya

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os

def rm(filename):
    os.remove(filename)
_

Jelas, metode

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
_6 kami pada saat ini tidak memberikan lebih dari metode
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
7 yang mendasarinya, tetapi basis kode kami akan meningkat, memungkinkan kami untuk menambahkan lebih banyak fungsi di sini

Mari kita tulis sebuah test case tradisional, mis. e. , tanpa tiruan

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")

Kasing uji kami cukup sederhana, tetapi setiap kali dijalankan, file sementara dibuat dan kemudian dihapus. Selain itu, kami tidak memiliki cara untuk menguji apakah metode

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
6 kami dengan benar meneruskan argumen ke panggilan
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
7. Kita dapat berasumsi bahwa itu berdasarkan tes di atas, tetapi masih banyak yang harus diinginkan

Refactoring dengan Python Mocks

Mari refactor test case kita menggunakan

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")

Dengan pemfaktoran ulang ini, kami telah mengubah secara mendasar cara pengoperasian pengujian. Sekarang, kami memiliki orang dalam, objek yang dapat kami gunakan untuk memverifikasi fungsionalitas objek lain

Potensi Jebakan Mocking Python

Salah satu hal pertama yang harus menonjol adalah bahwa kami menggunakan dekorator metode

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
1 untuk meniru objek yang terletak di
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
2, dan menyuntikkan tiruan itu ke dalam metode uji kasus kami. Bukankah lebih masuk akal untuk hanya mengejek
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
3 itu sendiri, daripada merujuknya di
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
2?

Nah, Python adalah ular yang licik dalam hal mengimpor dan mengelola modul. Saat runtime, modul

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
_5 memiliki
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
3 sendiri yang diimpor ke dalam lingkup lokalnya sendiri dalam modul. Jadi, jika kita mengejek
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
_3, kita tidak akan melihat efek tiruan di modul
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
5

Mantra untuk terus diulang adalah ini

Mengejek item di mana ia digunakan, bukan dari mana asalnya

Jika Anda perlu meniru modul

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)
_9 untuk
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
0, Anda mungkin perlu menerapkan tiruan ke
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
1, karena setiap modul menyimpan impornya sendiri

Dengan jebakan itu, mari kita terus mengejek

Menambahkan Validasi ke 'rm'

Metode

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
_6 yang didefinisikan sebelumnya terlalu disederhanakan. Kami ingin memvalidasi bahwa jalur ada dan merupakan file sebelum mencoba menghapusnya secara membabi buta. Mari refactor
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
_6 menjadi sedikit lebih pintar

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

def rm(filename):
    if os.path.isfile(filename):
        os.remove(filename)

Besar. Sekarang, mari kita sesuaikan test case kita untuk menjaga cakupan

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")

Paradigma pengujian kami telah berubah total. Kami sekarang dapat memverifikasi dan memvalidasi fungsionalitas internal metode tanpa efek samping apa pun

Penghapusan File sebagai Layanan dengan Mock Patch

Sejauh ini, kami hanya bekerja dengan menyediakan tiruan untuk fungsi, tetapi tidak untuk metode pada objek atau kasus di mana tiruan diperlukan untuk mengirimkan parameter. Mari kita bahas metode objek terlebih dahulu

Kita akan mulai dengan refactor metode

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
6 ke dalam kelas layanan. Sebenarnya tidak ada kebutuhan yang dapat dibenarkan, per se, untuk mengenkapsulasi fungsi sederhana seperti itu ke dalam sebuah objek, tetapi setidaknya akan membantu kami mendemonstrasikan konsep kunci dalam
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9. Mari refactor

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(filename):
        if os.path.isfile(filename):
            os.remove(filename)

Anda akan melihat bahwa tidak banyak yang berubah dalam kasus pengujian kami

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")

Bagus, sekarang kita tahu bahwa

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
6 berfungsi sesuai rencana. Mari buat layanan lain yang mendeklarasikannya sebagai dependensi

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(self, filename):
        if os.path.isfile(filename):
            os.remove(filename)
            

class UploadService(object):

    def __init__(self, removal_service):
        self.removal_service = removal_service
        
    def upload_complete(self, filename):
        self.removal_service.rm(filename)

Karena kami sudah memiliki cakupan pengujian pada

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
_6, kami tidak akan memvalidasi fungsi internal metode
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
6 dalam pengujian kami terhadap
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
9. Sebaliknya, kami hanya akan menguji (tanpa efek samping, tentu saja) yang
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
9 memanggil metode
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(filename):
        if os.path.isfile(filename):
            os.remove(filename)
1, yang kami tahu "hanya berfungsi ™" dari kasus pengujian kami sebelumnya

Ada dua cara untuk melakukannya

  1. Meniru metode
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    import os
    import os.path
    
    class RemovalService(object):
        """A service for removing objects from the filesystem."""
    
        def rm(filename):
            if os.path.isfile(filename):
                os.remove(filename)
    
    _1 itu sendiri
  2. Berikan contoh yang ditiru dalam konstruktor
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    from mymodule import rm
    
    import mock
    import unittest
    
    class RmTestCase(unittest.TestCase):
        
        @mock.patch('mymodule.os.path')
        @mock.patch('mymodule.os')
        def test_rm(self, mock_os, mock_path):
            # set up the mock
            mock_path.isfile.return_value = False
            
            rm("any path")
            
            # test that the remove call was NOT called.
            self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
            
            # make the file 'exist'
            mock_path.isfile.return_value = True
            
            rm("any path")
            
            mock_os.remove.assert_called_with("any path")
    
    9

Karena kedua metode tersebut sering kali penting dalam pengujian unit, kami akan meninjau keduanya

Pilihan 1. Metode Mocking Instance

Pustaka

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9 memiliki dekorator metode khusus untuk mengejek metode dan properti instance objek, dekorator
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(filename):
        if os.path.isfile(filename):
            os.remove(filename)
5

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService, UploadService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
      
      
class UploadServiceTestCase(unittest.TestCase):

    @mock.patch.object(RemovalService, 'rm')
    def test_upload_complete(self, mock_rm):
        # build our dependencies
        removal_service = RemovalService()
        reference = UploadService(removal_service)
        
        # call upload_complete, which should, in turn, call `rm`:
        reference.upload_complete("my uploaded file")
        
        # check that it called the rm method of any RemovalService
        mock_rm.assert_called_with("my uploaded file")
        
        # check that it called the rm method of _our_ removal_service
        removal_service.rm.assert_called_with("my uploaded file")

Besar. Kami telah memvalidasi bahwa

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
_9 berhasil memanggil metode
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os):
        rm("any path")
        # test that rm called os.remove with the right parameters
        mock_os.remove.assert_called_with("any path")
6 instance kami. Perhatikan sesuatu yang menarik di sana? . Artinya, kita benar-benar dapat memeriksa instans itu sendiri. Jika Anda ingin melihat lebih banyak, coba masukkan breakpoint dalam kode tiruan Anda untuk memahami cara kerja mekanisme penambalan

Perangkap Mock Patch. Pesanan Dekorator

Saat menggunakan banyak dekorator pada metode pengujian Anda, urutan itu penting, dan agak membingungkan. Pada dasarnya, saat memetakan dekorator ke parameter metode,. Pertimbangkan contoh ini

    @mock.patch('mymodule.sys')
    @mock.patch('mymodule.os')
    @mock.patch('mymodule.os.path')
    def test_something(self, mock_os_path, mock_os, mock_sys):
        pass

Perhatikan bagaimana parameter kita dicocokkan dengan urutan dekorator terbalik? . Dengan beberapa dekorator metode, inilah urutan eksekusi dalam pseudocode

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
0

Karena tambalan ke ________ 35 ______ 0 adalah tambalan terluar, tambalan akan dieksekusi terakhir, menjadikannya parameter terakhir dalam argumen metode pengujian yang sebenarnya. Catat ini dengan baik dan gunakan debugger saat menjalankan pengujian Anda untuk memastikan bahwa parameter yang tepat dimasukkan dalam urutan yang benar

pilihan 2. Membuat Mock Instance

Alih-alih mengolok-olok metode contoh tertentu, kami malah bisa menyediakan contoh tiruan ke

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
9 dengan konstruktornya. Saya lebih suka opsi 1 di atas, karena jauh lebih tepat, tetapi ada banyak kasus di mana opsi 2 mungkin efisien atau perlu. Mari refactor pengujian kita lagi

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
_1

Dalam contoh ini, kami bahkan tidak perlu menambal fungsionalitas apa pun, kami cukup membuat spek otomatis untuk kelas

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
6, lalu menyuntikkan instance ini ke
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import mock
import unittest

class RmTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # set up the mock
        mock_path.isfile.return_value = False
        
        rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        rm("any path")
        
        mock_os.remove.assert_called_with("any path")
9 kami untuk memvalidasi fungsionalitas

Metode ini membuat instance yang setara secara fungsional ke kelas yang disediakan. Artinya, secara praktis, adalah bahwa ketika instance yang dikembalikan berinteraksi, itu akan menimbulkan pengecualian jika digunakan dengan cara ilegal. Lebih khusus lagi, jika suatu metode dipanggil dengan jumlah argumen yang salah, pengecualian akan dimunculkan. Ini sangat penting karena refaktor terjadi. Saat perpustakaan berubah, tes berhenti dan itu diharapkan. Tanpa menggunakan spek otomatis, pengujian kami akan tetap lulus meskipun implementasi yang mendasarinya rusak

Batu sandungan. Kelas
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
5 dan
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
6

Pustaka

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9 juga menyertakan dua kelas penting tempat sebagian besar fungsi internal dibangun.
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
_5 dan. Saat diberi pilihan untuk menggunakan instance
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
_5, instance
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
6, atau spek otomatis, selalu gunakan spek otomatis, karena ini membantu pengujian Anda tetap waras untuk perubahan di masa mendatang. Ini karena
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
5 dan
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
6 menerima semua panggilan metode dan penetapan properti terlepas dari API yang mendasarinya. Pertimbangkan kasus penggunaan berikut

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
_2

Kita dapat menguji ini dengan contoh

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import RemovalService

import mock
import unittest

class RemovalServiceTestCase(unittest.TestCase):
    
    @mock.patch('mymodule.os.path')
    @mock.patch('mymodule.os')
    def test_rm(self, mock_os, mock_path):
        # instantiate our service
        reference = RemovalService()
        
        # set up the mock
        mock_path.isfile.return_value = False
        
        reference.rm("any path")
        
        # test that the remove call was NOT called.
        self.assertFalse(mock_os.remove.called, "Failed to not remove the file if not present.")
        
        # make the file 'exist'
        mock_path.isfile.return_value = True
        
        reference.rm("any path")
        
        mock_os.remove.assert_called_with("any path")
5 seperti ini

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
_3

Logika ini tampaknya masuk akal, tetapi mari kita ubah metode

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(self, filename):
        if os.path.isfile(filename):
            os.remove(filename)
            

class UploadService(object):

    def __init__(self, removal_service):
        self.removal_service = removal_service
        
    def upload_complete(self, filename):
        self.removal_service.rm(filename)
5 untuk mengambil lebih banyak parameter

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
_4

Jalankan ulang pengujian Anda, dan Anda akan menemukan bahwa itu masih lolos. Itu karena itu tidak dibangun dengan API Anda yang sebenarnya. Inilah mengapa Anda harus selalu menggunakan metode

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(self, filename):
        if os.path.isfile(filename):
            os.remove(filename)
            

class UploadService(object):

    def __init__(self, removal_service):
        self.removal_service = removal_service
        
    def upload_complete(self, filename):
        self.removal_service.rm(filename)
_6 dan parameter
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(self, filename):
        if os.path.isfile(filename):
            os.remove(filename)
            

class UploadService(object):

    def __init__(self, removal_service):
        self.removal_service = removal_service
        
    def upload_complete(self, filename):
        self.removal_service.rm(filename)
7 dengan dekorator
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(self, filename):
        if os.path.isfile(filename):
            os.remove(filename)
            

class UploadService(object):

    def __init__(self, removal_service):
        self.removal_service = removal_service
        
    def upload_complete(self, filename):
        self.removal_service.rm(filename)
8 dan
#!/usr/bin/env python
# -*- coding: utf-8 -*-

import os
import os.path

class RemovalService(object):
    """A service for removing objects from the filesystem."""

    def rm(self, filename):
        if os.path.isfile(filename):
            os.remove(filename)
            

class UploadService(object):

    def __init__(self, removal_service):
        self.removal_service = removal_service
        
    def upload_complete(self, filename):
        self.removal_service.rm(filename)
9

Contoh Mock Python. Mengejek Panggilan API Facebook

Untuk menyelesaikannya, mari kita tulis contoh tiruan python dunia nyata yang lebih dapat diterapkan, yang telah kami sebutkan di pendahuluan. memposting pesan ke Facebook. Kami akan menulis kelas pembungkus yang bagus dan kasus uji yang sesuai

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
5

Ini kasus pengujian kami, yang memeriksa bahwa kami memposting pesan tanpa benar-benar memposting pesan

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
_6

Seperti yang telah kita lihat sejauh ini, sangat mudah untuk mulai menulis tes yang lebih cerdas dengan

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9 di Python

Kesimpulan

Pustaka

#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9 Python, jika sedikit membingungkan untuk dikerjakan, adalah pengubah permainan untuk pengujian unit. Kami telah mendemonstrasikan kasus penggunaan umum untuk mulai menggunakan
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from mymodule import rm

import os.path
import tempfile
import unittest

class RmTestCase(unittest.TestCase):

    tmpfilepath = os.path.join(tempfile.gettempdir(), "tmp-testfile")

    def setUp(self):
        with open(self.tmpfilepath, "wb") as f:
            f.write("Delete me!")
        
    def test_rm(self):
        # remove the file
        rm(self.tmpfilepath)
        # test that it was actually removed
        self.assertFalse(os.path.isfile(self.tmpfilepath), "Failed to remove the file.")
9 dalam pengujian unit, dan semoga artikel ini akan membantu pengembang Python mengatasi rintangan awal dan menulis kode yang sangat baik dan teruji


Bacaan Lebih Lanjut di Toptal Engineering Blog

  • Pengujian Unit di Flutter. Dari Workflow Essentials ke Skenario Kompleks

Memahami dasar-dasarnya

Apa yang mengejek dalam pengujian unit?

Mengejek mensimulasikan keberadaan dan perilaku objek nyata, memungkinkan insinyur perangkat lunak untuk menguji kode dalam berbagai skenario hipotetis tanpa perlu menggunakan panggilan sistem yang tak terhitung jumlahnya. Mengejek dengan demikian dapat secara drastis meningkatkan kecepatan dan efisiensi pengujian unit

Apa yang mengejek dengan Python?

Mengejek dengan Python berarti yang paling unik. Pustaka mock digunakan untuk mengganti bagian sistem dengan objek tiruan, memungkinkan pengujian unit yang lebih mudah dan lebih efisien daripada yang mungkin dilakukan

Tag

PythonMockUnittest

Freelancer? Temukan pekerjaan Anda berikutnya.

Pekerjaan Pengembang Python

Lihat profil lengkap

Naftuli Kay

Insinyur Perangkat Lunak Lepas

Tentang Penulis

Naftuli adalah pengembang perangkat lunak dan administrator sistem dengan kemampuan kelas atas di berbagai platform, bahasa, dan sistem

Pekerjakan Naftuli

Komentar

Enrique Conci

Pos Hebat. Ini sangat berguna

Enrique Conci

Pos Hebat. Ini sangat berguna

Gabriel Pozoz

Luar biasa, terima kasih

Gabriel Pozoz

Luar biasa, terima kasih

Alex Parra

Pos bagus

Alex Parra

Pos bagus

dd101

Tutorial insinyur top

dd101

Tutorial insinyur top

pebre79

Pos bagus. Koreksi kecil. os. jalur. isfile(self. tempfile) harus os. jalur. isfile(self. tmpfilepath)

pebre79

Pos bagus. Koreksi kecil. os. jalur. isfile(self. tempfile) harus os. jalur. isfile(self. tmpfilepath)

Jared Culp

When invoking the Facebook test suite, I get: AssertionError: Expected call: put_object(message='Hello World!') Actual call: put_object(, 'me', 'feed', message='Hello World!') The put_object method takes more params than just the message. However, changing autospec=False causes the method to pass! (like the last pitfall you discussed) Could you shed some light into this? Thanks for the article, its resolved many confusions I had with mocking in python.

Jared Culp

When invoking the Facebook test suite, I get: AssertionError: Expected call: put_object(message='Hello World!') Actual call: put_object(, 'me', 'feed', message='Hello World!') The put_object method takes more params than just the message. However, changing autospec=False causes the method to pass! (like the last pitfall you discussed) Could you shed some light into this? Thanks for the article, its resolved many confusions I had with mocking in python.

mengejar

Pos bagus. thx btw di kelas Layanan Penghapusan. def rm(nama file) harus def rm(self, nama file). )

mengejar

Pos bagus. thx btw di kelas Layanan Penghapusan. def rm(nama file) harus def rm(self, nama file). )

Ian Liu Rodrigues

saya bingung. Bagi saya inti dari abstraksi adalah bahwa penerapannya tidak penting; . Jadi, jika Anda memfaktorkan ulang metode "rm" untuk menggunakan, katakanlah, subproses. call(["rm", arg]) unit test akan gagal meskipun implementasinya akan mempertahankan perilaku yang benar. Saya tidak membaca seluruh posting, maaf untuk itu. Harap tunjukkan kesalahan apa pun dalam komentar saya

Ian Liu Rodrigues

saya bingung. Bagi saya inti dari abstraksi adalah bahwa penerapannya tidak penting; . Jadi, jika Anda memfaktorkan ulang metode "rm" untuk menggunakan, katakanlah, subproses. call(["rm", arg]) unit test akan gagal meskipun implementasinya akan mempertahankan perilaku yang benar. Saya tidak membaca seluruh posting, maaf untuk itu. Harap tunjukkan kesalahan apa pun dalam komentar saya

DrWatson

Mulailah dengan menjelaskan secara mental apa fungsi yang diuji. Jika Anda berpikir "rm(nama file) menghapus file," itu akan benar dari perspektif pemanggil, tetapi saat unit mengujinya Anda bisa lebih spesifik dan mendeskripsikannya sebagai "rm(nama file) menggunakan os. hapus untuk menghapus file. " Kami akan percaya bahwa os. hapus tahu bagaimana melakukan tugasnya dan kami tidak perlu khawatir tentang itu. Yang kami pedulikan hanyalah bahwa itu digunakan oleh fungsi rm kami. Untuk fungsi one-liner kedengarannya dibuat-buat dan tidak perlu. Faktanya, seseorang dapat membuat argumen yang valid bahwa fungsi seperti itu bahkan tidak memerlukan pengujian unit. Saat fungsi itu berkembang, Anda akan melihat bahwa akan ada lebih banyak nuansa tentang bagaimana logika mengalir sehingga Anda akan memiliki perilaku yang cukup untuk diuji dan tidak akan senang mengkhawatirkan efek samping dari kode eksternal. Ini hampir seperti permainan menggambar garis seberapa jauh Anda bersedia melangkah untuk memverifikasi apakah kode Anda berfungsi. Menggunakan tiruan Anda dapat menggambar garis itu lebih dekat ke kode Anda dan pengujian Anda biasanya akan menjadi lebih cepat dan lebih tepat sasaran

DrWatson

Mulailah dengan menjelaskan secara mental apa fungsi yang diuji. Jika Anda berpikir "rm(nama file) menghapus file," itu akan benar dari perspektif pemanggil, tetapi saat unit mengujinya Anda bisa lebih spesifik dan mendeskripsikannya sebagai "rm(nama file) menggunakan os. hapus untuk menghapus file. " Kami akan percaya bahwa os. hapus tahu bagaimana melakukan tugasnya dan kami tidak perlu khawatir tentang itu. Yang kami pedulikan hanyalah bahwa itu digunakan oleh fungsi rm kami. Untuk fungsi one-liner kedengarannya dibuat-buat dan tidak perlu. Faktanya, seseorang dapat membuat argumen yang valid bahwa fungsi seperti itu bahkan tidak memerlukan pengujian unit. Saat fungsi itu berkembang, Anda akan melihat bahwa akan ada lebih banyak nuansa tentang bagaimana logika mengalir sehingga Anda akan memiliki perilaku yang cukup untuk diuji dan tidak akan senang mengkhawatirkan efek samping dari kode eksternal. Ini hampir seperti permainan menggambar garis seberapa jauh Anda bersedia melangkah untuk memverifikasi apakah kode Anda berfungsi. Menggunakan tiruan Anda dapat menggambar garis itu lebih dekat ke kode Anda dan pengujian Anda biasanya akan menjadi lebih cepat dan lebih tepat sasaran

袁 晨思

Kode contoh "Opsi 2" memiliki masalah "kelas UploadServiceTestCase" metode "def test_upload_complete(self, mock_rm)" seharusnya tidak ada param "mock_rm"

袁 晨思

Kode contoh "Opsi 2" memiliki masalah "kelas UploadServiceTestCase" metode "def test_upload_complete(self, mock_rm)" seharusnya tidak ada param "mock_rm"

Sven

Diilustrasikan dengan bagus. Bagus sekali. Satu hal lagi yang menarik adalah mengejek metode objek dalam warisan. Terutama metode induk dari suatu objek yang perlu diuji secara terisolasi. Sehingga objek yang diberikan seperti mixin yang mengharapkan metode induk sudah ada, yang tersedia pada waktu penggunaan mixin, dapat diuji dengan mengejek metode induk yang diharapkan nanti ini. Saya tidak begitu yakin apakah ini benar-benar mungkin

Sven

Diilustrasikan dengan bagus. Bagus sekali. Satu hal lagi yang menarik adalah mengejek metode objek dalam warisan. Terutama metode induk dari suatu objek yang perlu diuji secara terisolasi. Sehingga objek yang diberikan seperti mixin yang mengharapkan metode induk sudah ada, yang tersedia pada waktu penggunaan mixin, dapat diuji dengan mengejek metode induk yang diharapkan nanti ini. Saya tidak begitu yakin apakah ini benar-benar mungkin

Kevin Audleman

Astaga, Anda baru saja membantu saya memahami mengapa saya tidak dapat menambal kelas Klien busa yang digunakan salah satu aplikasi saya. Saya melakukan @patch('suds. klien. Client') bukannya @patch('myapp. file saya. Klien'). Saya sudah frustrasi selama berhari-hari. terima kasih

Kevin Audleman

Astaga, Anda baru saja membantu saya memahami mengapa saya tidak dapat menambal kelas Klien busa yang digunakan salah satu aplikasi saya. Saya melakukan @patch('suds. klien. Client') bukannya @patch('myapp. file saya. Klien'). Saya sudah frustrasi selama berhari-hari. terima kasih

raphael_carvalho

Pos bagus

raphael_carvalho

Pos bagus

jimofthecorn

Posting yang bermanfaat, terima kasih. Beberapa kesalahan sintaks copypaste. Layanan Penghapusan pertama Anda. rm() tidak memiliki argumen 'self', & UploadServiceTestCase ke-2. test_upload_complete() memiliki argumen 'mock_rm' yang asing

jimofthecorn

Posting yang bermanfaat, terima kasih. Beberapa kesalahan sintaks copypaste. Layanan Penghapusan pertama Anda. rm() tidak memiliki argumen 'self', & UploadServiceTestCase ke-2. test_upload_complete() memiliki argumen 'mock_rm' yang asing

Sachin Kale

Baru saja memulai pengembangan dengan Python. Ini adalah artikel yang sangat berguna untuk menulis tes unit. Terima kasih banyak

Sachin Kale

Baru saja memulai pengembangan dengan Python. Ini adalah artikel yang sangat berguna untuk menulis tes unit. Terima kasih banyak

Sebelas

Sangat Keren~ Terima Kasih

Sebelas

Sangat Keren~ Terima Kasih

Jonathan Hartley

@ian_liu. disqus Pengamatan anda benar. Oleh karena itu, seseorang tidak boleh terlalu mengandalkan ejekan dalam pengujian Anda. Namun, digunakan dengan bijaksana, mereka bisa sangat berguna. Temukan keseimbangan pragmatis Anda sendiri. Mungkin jika Anda memiliki layanan yang memiliki API yang ditentukan, masuk akal untuk mengejeknya karena intinya adalah bahwa kode panggilan Anda harus membuat panggilan seperti yang ditentukan oleh API

Jonathan Hartley

@ian_liu. disqus Pengamatan anda benar. Oleh karena itu, seseorang tidak boleh terlalu mengandalkan ejekan dalam pengujian Anda. Namun, digunakan dengan bijaksana, mereka bisa sangat berguna. Temukan keseimbangan pragmatis Anda sendiri. Mungkin jika Anda memiliki layanan yang memiliki API yang ditentukan, masuk akal untuk mengejeknya karena intinya adalah bahwa kode panggilan Anda harus membuat panggilan seperti yang ditentukan oleh API

xiaohanyu

Ini sangat membantu, terima kasih banyak

xiaohanyu

Ini sangat membantu, terima kasih banyak

kazi

Artikel yang Sangat Bermanfaat. Bagus sekali

kazi

Artikel yang Sangat Bermanfaat. Bagus sekali

lengkungan

Jika Anda meneruskan autospec=True ke patch maka ia melakukan patching dengan objek fungsi nyata. Objek fungsi ini memiliki tanda tangan yang sama dengan objek yang digantikannya, tetapi didelegasikan ke tiruan di bawah tenda. Anda masih membuat tiruan Anda secara otomatis dengan cara yang persis sama seperti sebelumnya. Apa artinya, adalah bahwa jika Anda menggunakannya untuk menambal metode tidak terikat pada kelas, fungsi yang diejek akan diubah menjadi metode terikat jika diambil dari sebuah instance. Singkat cerita, put_object memiliki "self" yang diteruskan sebagai argumen pertama. Dan jika autospec = True maka objek fungsi tiruan memiliki tanda tangan yang sama dengan yang diganti. Itulah alasan mendapatkan kesalahan pernyataan dengan autospec = True

lengkungan

Jika Anda meneruskan autospec=True ke patch maka ia melakukan patching dengan objek fungsi nyata. Objek fungsi ini memiliki tanda tangan yang sama dengan objek yang digantikannya, tetapi didelegasikan ke tiruan di bawah tenda. Anda masih membuat tiruan Anda secara otomatis dengan cara yang persis sama seperti sebelumnya. Apa artinya, adalah bahwa jika Anda menggunakannya untuk menambal metode tidak terikat pada kelas, fungsi yang diejek akan diubah menjadi metode terikat jika diambil dari sebuah instance. Singkat cerita, put_object memiliki "self" yang diteruskan sebagai argumen pertama. Dan jika autospec = True maka objek fungsi tiruan memiliki tanda tangan yang sama dengan yang diganti. Itulah alasan mendapatkan kesalahan pernyataan dengan autospec = True

Andriy Petrashenko

Halo, Kevin. Saya sedang menulis pengujian unit dalam proyek Django menggunakan busa tetapi tidak tahu cara mengejeknya. Tolong kirimkan saya potongan kode dari tes yang Anda sebutkan di komentar Anda? . Terima kasih Andrey

Andriy Petrashenko

Halo, Kevin. Saya sedang menulis pengujian unit dalam proyek Django menggunakan busa tetapi tidak tahu cara mengejeknya. Tolong kirimkan saya potongan kode dari tes yang Anda sebutkan di komentar Anda? . Terima kasih Andrey

Diego "Ocelotl" Hurtado Piment

Luar biasa, sangat menyukainya

Diego "Ocelotl" Hurtado Piment

Luar biasa, sangat menyukainya

Scott Pigman

Masalah besar dengan menggunakan tiruan yang tidak dapat saya pahami adalah bahwa tes yang Anda tulis (a) harus sangat menyadari implementasi fungsi yang sedang diuji, dan (b) Anda berasumsi bahwa . Misalkan saya sedang menulis fungsi untuk menghapus direktori dan semua file di dalamnya, tetapi saya salah percaya bahwa os. rmdir() akan menghapus semua file di dalam direktori alih-alih menimbulkan kesalahan. Saya bisa menulis fungsi yang memanggil os. rmdir() dan saya bisa menulis unittest yang mengolok-olok os. rmdir dan menegaskan bahwa itu dipanggil dan pengujian saya akan lulus - tetapi fungsinya tidak akan berfungsi dalam kehidupan nyata jadi apa nilai dari pengujian tersebut, sungguh? . Saya ingin menggunakan objek tiruan; . Mampu menguji objek tiruan akan sangat mengurangi waktu siklus pengujian saya. Tetapi sebagian besar waktu tidak sepenuhnya jelas bagaimana panggilan API tertentu akan benar-benar berfungsi sehingga mengejek panggilan dan menyatakan bahwa itu dipanggil tidak banyak membantu saya.

Scott Pigman

Masalah besar dengan menggunakan tiruan yang tidak dapat saya pahami adalah bahwa tes yang Anda tulis (a) harus sangat menyadari implementasi fungsi yang sedang diuji, dan (b) Anda berasumsi bahwa . Misalkan saya sedang menulis fungsi untuk menghapus direktori dan semua file di dalamnya, tetapi saya salah percaya bahwa os. rmdir() akan menghapus semua file di dalam direktori alih-alih menimbulkan kesalahan. Saya bisa menulis fungsi yang memanggil os. rmdir() dan saya bisa menulis unittest yang mengolok-olok os. rmdir dan menegaskan bahwa itu dipanggil dan pengujian saya akan lulus - tetapi fungsinya tidak akan berfungsi dalam kehidupan nyata jadi apa nilai dari pengujian tersebut, sungguh? . Saya ingin menggunakan objek tiruan; . Mampu menguji objek tiruan akan sangat mengurangi waktu siklus pengujian saya. Tetapi sebagian besar waktu tidak sepenuhnya jelas bagaimana panggilan API tertentu akan benar-benar berfungsi sehingga mengejek panggilan dan menyatakan bahwa itu dipanggil tidak banyak membantu saya.

Mike

Terima kasih postingan yang bagus

Mike

Terima kasih postingan yang bagus

Dan Stromberg

Menarik bahwa Anda bisa mengejek. patch os dan kemudian os. jalan, tetapi jika Anda mengejek os. jalan dan kemudian os, os. jalan berakhir tidak diejek. Apakah ini karena mock (os) ke-2 menggantikan yang pertama (os. jalur)?

Dan Stromberg

Menarik bahwa Anda bisa mengejek. patch os dan kemudian os. jalan, tetapi jika Anda mengejek os. jalan dan kemudian os, os. jalan berakhir tidak diejek. Apakah ini karena mock (os) ke-2 menggantikan yang pertama (os. jalur)?

Dan Stromberg

Saya pikir beberapa metode kelas Anda mungkin sedikit salah. Tidakkah Anda memerlukan dekorator @staticmethod untuk metode yang tidak menerima self atau cls?

Dan Stromberg

Saya pikir beberapa metode kelas Anda mungkin sedikit salah. Tidakkah Anda memerlukan dekorator @staticmethod untuk metode yang tidak menerima self atau cls?

Dan Stromberg

Juga. Dokumen yang luar biasa - Saya belajar banyak

Dan Stromberg

Juga. Dokumen yang luar biasa - Saya belajar banyak

amd

Saya setuju dengan Ian di sini; . Dan khususnya bagaimana ini diterjemahkan ke lingkungan di mana kelas TDD/BDD dipisahkan dari pengembang. Ini hanyalah praktik yang mengerikan sepanjang jalan

amd

Saya setuju dengan Ian di sini; . Dan khususnya bagaimana ini diterjemahkan ke lingkungan di mana kelas TDD/BDD dipisahkan dari pengembang. Ini hanyalah praktik yang mengerikan sepanjang jalan

Mark Schumacher

Pegang telepon, contoh facebook terakhir Anda. @mengejek. tambalan. objek (facebook. GraphAPI, 'put_object', autospec=True) seharusnya ini bukan @mock. tambalan. objek (simple_facebook. facebook. API Grafik, 'put_object', autospec=True) karena aturan yang Anda jelaskan di bagian atas posting Anda. "Saat runtime, modul mymodule memiliki os sendiri yang diimpor ke ruang lingkup lokalnya sendiri di dalam modul. "

Mark Schumacher

Pegang telepon, contoh facebook terakhir Anda. @mengejek. tambalan. objek (facebook. GraphAPI, 'put_object', autospec=True) seharusnya ini bukan @mock. tambalan. objek (simple_facebook. facebook. API Grafik, 'put_object', autospec=True) karena aturan yang Anda jelaskan di bagian atas posting Anda. "Saat runtime, modul mymodule memiliki os sendiri yang diimpor ke ruang lingkup lokalnya sendiri di dalam modul. "

space_monkey

Apa solusi alternatif untuk pengujian unit?

space_monkey

Apa solusi alternatif untuk pengujian unit?

Chris Brackert

Kenapa `@mock. tambalan. objek (facebook. Graph API, 'putobject', autospec=True)` bukanlah `@mock. tambalan. objek (simple_facebook. facebook. Grafik API, 'put_object', autospec=True)` jika kita ingin "Mengejek item di mana ia digunakan, bukan dari mana asalnya. "?

Chris Brackert

Kenapa `@mock. tambalan. objek (facebook. Graph API, 'putobject', autospec=True)` bukanlah `@mock. tambalan. objek (simple_facebook. facebook. Grafik API, 'put_object', autospec=True)` jika kita ingin "Mengejek item di mana ia digunakan, bukan dari mana asalnya. "?

Carl Dunham

Seperti biasa, Sandi Metz punya jawabannya. Dia menggunakan metafora kapsul luar angkasa yang sangat membantu. Dia membahas ini sekitar pukul 12. 00 dan 20. 00 https. // www. Youtube. com/watch?v=URSWYvyc42M

Carl Dunham

Seperti biasa, Sandi Metz punya jawabannya. Dia menggunakan metafora kapsul luar angkasa yang sangat membantu. Dia membahas ini sekitar pukul 12. 00 dan 20. 00 https. // www. Youtube. com/watch?v=URSWYvyc42M

Kavi Jivan

Di bawah Opsi 2. Membuat Instance Mock def test_upload_complete(self, mock_rm). seharusnya def test_upload_complete(self). Saya menduga kesalahan salin tempel dari contoh sebelumnya. Artikel bagus terima kasih

Kavi Jivan

Di bawah Opsi 2. Membuat Instance Mock def test_upload_complete(self, mock_rm). seharusnya def test_upload_complete(self). Saya menduga kesalahan salin tempel dari contoh sebelumnya. Artikel bagus terima kasih

Suzuki Teitaro

Pos Hebat

Suzuki Teitaro

Pos Hebat

Radek

File-Removal as a Service bagian, contoh pertama, Anda kehilangan diri di `def rm(filename). `. Saya menambahkan dekorator `@staticmethod` sebagai gantinya untuk memperbaikinya. Saya menambahkan py2. 7 contoh di sini. https. //github. com/radzhome/patch_example

Radek

File-Removal as a Service bagian, contoh pertama, Anda kehilangan diri di `def rm(filename). `. Saya menambahkan dekorator `@staticmethod` sebagai gantinya untuk memperbaikinya. Saya menambahkan py2. 7 contoh di sini. https. //github. com/radzhome/patch_example

Sergey11g

Contoh buruk. Jika file ada maka hapus. Kondisi balapan. Memperbaiki. mencoba untuk menghapus dan menangani pengecualian

Sergey11g

Contoh buruk. Jika file ada maka hapus. Kondisi balapan. Memperbaiki. mencoba untuk menghapus dan menangani pengecualian

Juanlu001

Terima kasih atas jawaban ini. Informasi lebih lanjut di sini https. //stackoverflow. com/a/27892226/554319

Juanlu001

Terima kasih atas jawaban ini. Informasi lebih lanjut di sini https. //stackoverflow. com/a/27892226/554319

Alessandro Surace

Terima kasih untuk postingan yang bagus ini. Itu menjelaskan beberapa tentang topik ini. Saya menulis semua kode dengan beberapa penyesuaian di sini. https. //github. com/zioalex/python-experiments/tree/master/Unittest/An_Introduction_to_Mocking_in_Python

Alessandro Surace

Terima kasih untuk postingan yang bagus ini. Itu menjelaskan beberapa tentang topik ini. Saya menulis semua kode dengan beberapa penyesuaian di sini. https. //github. com/zioalex/python-experiments/tree/master/Unittest/An_Introduction_to_Mocking_in_Python

钟钟

terima kasih. Ini benar-benar artikel yang berguna bagi saya untuk memahami cara menggunakan mock di python

钟钟

terima kasih. Ini benar-benar artikel yang berguna bagi saya untuk memahami cara menggunakan mock di python

ADITYA RAJ

Posting Hebat khususnya baris "Molok item di mana ia digunakan, bukan dari mana asalnya"

ADITYA RAJ

Posting Hebat khususnya baris "Molok item di mana ia digunakan, bukan dari mana asalnya"

Terry J. Reedy

>"fungsi tidak akan berfungsi dalam kehidupan nyata" Pengujian, manual dan otomatis, membantu dalam mengembangkan tambalan dan menangkap regresi. Saat saya memelihara IDLE (menggunakan versi tambalan terbaru), saya (semoga) berulang kali menguji langsung setiap perubahan yang saya buat, selain menjalankan dan menambahkan pengujian otomatis. Yang terakhir biasanya dikembangkan dari tes manual langsung. Mengolok-olok input kontrol, menghindari efek samping yang tidak dibutuhkan dan tidak diinginkan, dan menghemat waktu. Jadi, pengujian otomatis yang diejek melengkapi dan memperluas pengujian kehidupan nyata, daripada menggantinya sepenuhnya

ArcadiaSteve

Yup, saya butuh satu malam untuk memikirkan bug itu juga. Petunjuknya adalah pesan kesalahan yang berbicara tentang satu argumen versus dua. Jika tidak, contoh yang bagus. terima kasih

ArcadiaSteve

Karena kita sedang mendiskusikan (bug yang tidak disengaja) dalam contoh salin dan tempel s- yang saya sangat hargai btw, ada tutorial Python pemula yang bagus di luar sana yang disebut "Mempelajari Python dengan Cara yang Sulit. " Ini membawa Anda melalui semua dasar-dasar Python dengan banyak contoh salin dan tempel. Penulis menyarankan Anda untuk TIDAK menyalin dan menempel, tetapi sebenarnya, secara fisik mengetik semuanya dengan tangan. Ini melatih "jari gemuk" dan mata Anda untuk menyadari bahwa Anda (pembuat kode) adalah sumber kesalahan yang sebenarnya. Saat Anda mencapai akhir setiap modul, ada tes di mana dia kemudian memberi Anda contoh kode yang rumit, menggabungkan banyak blok penyusun modul itu. Contoh panjang terakhir ini sebenarnya DO berisi beberapa bug "tes" Anda untuk setiap bab adalah menghasilkan kode yang berfungsi, tetapi dengan itu Anda secara mental sudah mengantisipasi kesalahan yang paling mungkin terjadi. Hampir menyenangkan untuk meronta-ronta untuk menghasilkan kode bersih akhir dan sangat memuaskan. dan sangat "pembelajaran dunia nyata"

Bagaimana Anda memunculkan pengecualian di Python tiruan?

Meningkatkan pengecualian dengan tiruan . Jika Anda menyetel ini ke kelas atau instance pengecualian, maka pengecualian akan dimunculkan saat mock dipanggil. >>> mock = Mock(side_effect=Exception('Boom.

Bagaimana Anda menguji jika pengecualian dimunculkan Python?

Ada dua cara untuk menggunakan assertRaises. menggunakan argumen kata kunci . Lewati saja pengecualian, fungsi yang dapat dipanggil dan parameter dari fungsi yang dapat dipanggil sebagai argumen kata kunci yang akan menimbulkan pengecualian. Buat panggilan fungsi yang seharusnya memunculkan pengecualian dengan konteks.

Apa yang dilakukan @patch dengan Python?

patch() unittest. mock menyediakan mekanisme yang kuat untuk mengejek objek, yang disebut patch() , yang mencari objek dalam modul tertentu dan mengganti objek itu dengan Mock . Biasanya, Anda menggunakan patch() sebagai dekorator atau pengelola konteks untuk menyediakan ruang lingkup di mana Anda akan mengejek objek target.

Apa itu Autospec?

Penentuan otomatis dapat dilakukan melalui argumen autospec untuk ditambal, atau fungsi create_autospec(). Penetapan otomatis membuat objek tiruan yang memiliki atribut dan metode yang sama dengan objek yang diganti , dan setiap fungsi dan metode (termasuk konstruktor) memiliki kesamaan .