Chạy không ổn định với cấu trúc thư mục thử nghiệm điển hình


699

Cấu trúc thư mục rất phổ biến cho ngay cả một mô-đun Python đơn giản dường như là tách các bài kiểm tra đơn vị thành testthư mục riêng của chúng :

new_project/
    antigravity/
        antigravity.py
    test/
        test_antigravity.py
    setup.py
    etc.

ví dụ xem dự án Python này như thế nào .

Câu hỏi của tôi chỉ đơn giản là cách thông thường để thực sự chạy thử nghiệm là gì? Tôi nghi ngờ điều này là hiển nhiên đối với mọi người trừ tôi, nhưng bạn không thể chạy python test_antigravity.pytừ thư mục kiểm tra vì nó import antigravitysẽ thất bại vì mô-đun không nằm trên đường dẫn.

Tôi biết tôi có thể sửa đổi PYTHONPATH và các thủ thuật liên quan đến đường dẫn tìm kiếm khác, nhưng tôi không thể tin đó là cách đơn giản nhất - thật tốt nếu bạn là nhà phát triển nhưng không thực tế để mong người dùng của bạn sử dụng nếu họ chỉ muốn kiểm tra các bài kiểm tra đi qua.

Cách khác là chỉ sao chép tệp kiểm tra vào thư mục khác, nhưng có vẻ hơi ngu ngốc và bỏ lỡ điểm có chúng trong một thư mục riêng để bắt đầu.

Vì vậy, nếu bạn vừa tải nguồn về dự án mới của tôi, bạn sẽ chạy thử nghiệm đơn vị như thế nào? Tôi muốn một câu trả lời sẽ cho phép tôi nói với người dùng của mình: "Để chạy thử nghiệm đơn vị làm X."


5
@EMP Giải pháp thích hợp khi bạn cần đặt đường dẫn tìm kiếm là ... đặt đường dẫn tìm kiếm. Bạn đang mong đợi loại giải pháp nào?
Carl Meyer

7
@CarlMeyer một giải pháp khác tốt hơn là sử dụng unittestgiao diện dòng lệnh như được mô tả trong câu trả lời của tôi dưới đây để bạn không phải thêm thư mục vào đường dẫn.
Pierre

13
Tương tự ở đây. Tôi vừa bắt tay vào viết các bài kiểm tra đơn vị đầu tiên của mình cho một dự án Python nhỏ và mất vài ngày cố gắng lý luận rằng tôi không thể dễ dàng chạy thử trong khi giữ các nguồn của mình trong thư mục src và kiểm tra trong thư mục kiểm tra, dường như với bất kỳ khuôn khổ thử nghiệm hiện có. Cuối cùng tôi sẽ chấp nhận mọi thứ, tìm ra một cách; nhưng điều này đã được giới thiệu rất bực bội. (Và tôi là một cựu chiến binh thử nghiệm đơn vị bên ngoài Python.)
Ates Goral

Câu trả lời:


655

Theo tôi, giải pháp tốt nhất là sử dụng unittest giao diện dòng lệnh sẽ thêm thư mục vào sys.pathđể bạn không phải (thực hiện trong TestLoaderlớp).

Ví dụ cho một cấu trúc thư mục như thế này:

new_project
├── antigravity.py
└── test_antigravity.py

Bạn chỉ có thể chạy:

$ cd new_project
$ python -m unittest test_antigravity

Đối với cấu trúc thư mục như của bạn:

new_project
├── antigravity
   ├── __init__.py         # make it a package
   └── antigravity.py
└── test
    ├── __init__.py         # also make test a package
    └── test_antigravity.py

Và trong các mô-đun thử nghiệm bên trong testgói, bạn có thể nhập antigravitygói và các mô-đun như bình thường:

# import the package
import antigravity

# import the antigravity module
from antigravity import antigravity

# or an object inside the antigravity module
from antigravity.antigravity import my_object

Chạy một mô-đun thử nghiệm duy nhất:

Để chạy một mô-đun thử nghiệm duy nhất, trong trường hợp này test_antigravity.py:

$ cd new_project
$ python -m unittest test.test_antigravity

Chỉ cần tham khảo mô-đun kiểm tra giống như cách bạn nhập nó.

Chạy một trường hợp thử nghiệm hoặc phương pháp thử nghiệm:

Ngoài ra, bạn có thể chạy một TestCasehoặc một phương pháp thử nghiệm duy nhất:

$ python -m unittest test.test_antigravity.GravityTestCase
$ python -m unittest test.test_antigravity.GravityTestCase.test_method

Chạy tất cả các bài kiểm tra:

Bạn cũng có thể sử dụng khám phá thử nghiệm sẽ khám phá và chạy tất cả các thử nghiệm cho bạn, chúng phải là các mô-đun hoặc gói được đặt tên test*.py(có thể được thay đổi bằng -p, --patterncờ):

$ cd new_project
$ python -m unittest discover
$ # Also works without discover for Python 3
$ # as suggested by @Burrito in the comments
$ python -m unittest

Điều này sẽ chạy tất cả các test*.pymô-đun bên trong testgói.


53
python -m unittest discoversẽ tìm và chạy thử nghiệm trong testthư mục nếu chúng được đặt tên test*.py. Nếu bạn đặt tên thư mục con tests, hãy sử dụng python -m unittest discover -s testsvà nếu bạn đặt tên cho các tệp thử nghiệm antigravity_test.py, sử dụng python -m unittest discover -s tests -p '*test.py' Tên tệp có thể sử dụng dấu gạch dưới nhưng không phải dấu gạch ngang.
Mike3d0g

10
Điều này không thành công đối với tôi trên Python 3 do lỗi ImportError: No module named 'test.test_antigravity'do xung đột với mô đun con thử nghiệm của thư viện không đáng tin cậy nhất. Có lẽ một chuyên gia có thể xác nhận và thay đổi tên thư mục con trả lời thành ví dụ: 'tests' (số nhiều).
expz

9
Tôi test_antigravity.pyvẫn ném một lỗi nhập cho cả hai import antigravityfrom antigravity import antigravity, là tốt. Tôi có cả hai __init_.pytập tin và tôi đang gọi python3 -m unittest discovertừ new projectthư mục. Điều gì khác có thể sai?
imrek

19
tập tin test/__init__.pyrất quan trọng ở đây, ngay cả khi trống
Francois

3
@ Mike3d0g không chắc bạn có ý ám chỉ rằng tên thư mục testlà đặc biệt ... nhưng chỉ để ghi lại, thì không. : P python -m unittest discoverhoạt động với các tệp kiểm tra tests/cũng như test/.
ryan

49

Giải pháp đơn giản nhất cho người dùng của bạn là cung cấp một tập lệnh thực thi (runtests.py hoặc một số như vậy) để khởi động môi trường kiểm tra cần thiết, bao gồm, nếu cần, thêm thư mục dự án gốc của bạn sys.pathtạm thời. Điều này không yêu cầu người dùng đặt các biến môi trường, một cái gì đó như thế này hoạt động tốt trong tập lệnh bootstrap:

import sys, os

sys.path.insert(0, os.path.dirname(__file__))

Sau đó, hướng dẫn của bạn cho người dùng của bạn có thể đơn giản như " python runtests.py".

Tất nhiên, nếu con đường bạn cần thực sự là os.path.dirname(__file__) , thì bạn không cần phải thêm nó sys.pathvào; Python luôn đặt thư mục của tập lệnh hiện đang chạy vào đầu sys.path, vì vậy tùy thuộc vào cấu trúc thư mục của bạn, chỉ cần xác định vị trí của bạn runtests.pyở đúng nơi có thể là tất cả những gì cần thiết.

Ngoài ra, mô-đun không đáng tin cậy nhất trong Python 2.7+ (được nhập lại là unittest2 cho Python 2.6 trở về trước) hiện đã có tính năng phát hiện thử nghiệm , do đó, mũi không còn cần thiết nếu bạn muốn khám phá thử nghiệm tự động: hướng dẫn sử dụng của bạn có thể đơn giản như python -m unittest discover.


Tôi đặt một số bài kiểm tra trong thư mục con như "Thiếu tá". Chúng có thể chạy với python -m khám phá không đáng tin cậy nhất nhưng làm thế nào tôi có thể chọn chỉ chạy một trong số chúng. Nếu tôi chạy python -m unittest tests / testxxxxx thì nó không thành công cho vấn đề đường dẫn. Vì chế độ dicovery giải quyết mọi thứ, tôi mong đợi rằng có một mẹo khác để giải quyết vấn đề đường dẫn mà không cần sửa lỗi đường dẫn mã hóa mà bạn đề xuất ở điểm đầu tiên
Frederic Bazin

2
@FredericBazin Đừng sử dụng khám phá nếu bạn chỉ muốn một tệp thử nghiệm hoặc tệp thử nghiệm, chỉ cần đặt tên cho mô-đun bạn muốn chạy. Nếu bạn đặt tên cho nó là một đường dẫn chấm mô-đun (chứ không phải là đường dẫn tệp), nó có thể tìm ra đường dẫn tìm kiếm chính xác. Xem câu trả lời của Peter để biết thêm chi tiết.
Carl Meyer

Vụ hack này rất hữu ích trong một kịch bản mà tôi phải chạy một cái gì đó như thế nào python -m pdb tests\test_antigravity.py. Bên trong pdb, tôi đã thực thi sys.path.insert(0, "antigravity")cho phép câu lệnh nhập giải quyết như thể tôi đang chạy mô-đun.
ixe013

23

Tôi thường tạo một tập lệnh "chạy thử" trong thư mục dự án (tập lệnh chung cho cả thư mục nguồn và test ) tải bộ "Tất cả các bài kiểm tra" của tôi. Đây thường là mã soạn sẵn, vì vậy tôi có thể sử dụng lại từ dự án này sang dự án khác.

run_tests.py:

import unittest
import test.all_tests
testSuite = test.all_tests.create_test_suite()
text_runner = unittest.TextTestRunner().run(testSuite)

test / all_tests.py (từ Làm cách nào để tôi chạy tất cả các bài kiểm tra đơn vị Python trong một thư mục? )

import glob
import unittest

def create_test_suite():
    test_file_strings = glob.glob('test/test_*.py')
    module_strings = ['test.'+str[5:len(str)-3] for str in test_file_strings]
    suites = [unittest.defaultTestLoader.loadTestsFromName(name) \
              for name in module_strings]
    testSuite = unittest.TestSuite(suites)
    return testSuite

Với thiết lập này, bạn thực sự có thể chỉ include antigravitytrong các mô-đun thử nghiệm của mình. Nhược điểm là bạn sẽ cần nhiều mã hỗ trợ hơn để thực hiện một thử nghiệm cụ thể ... Tôi chỉ chạy chúng mọi lúc.


1
Tôi cũng muốn có một run testskịch bản trong thư mục dự án và tìm thấy một cách sạch sẽ hơn nhiều để làm điều đó. Rất khuyến khích.
z33k

18

Từ bài viết bạn liên kết đến:

Tạo một tệp test_modulename.py và đặt các bài kiểm tra khó nhất của bạn vào đó. Vì các mô-đun kiểm tra nằm trong một thư mục riêng biệt từ mã của bạn, bạn có thể cần thêm thư mục mẹ của mô-đun vào PYTHONPATH để chạy chúng:

$ cd /path/to/googlemaps

$ export PYTHONPATH=$PYTHONPATH:/path/to/googlemaps/googlemaps

$ python test/test_googlemaps.py

Cuối cùng, có một khung thử nghiệm đơn vị phổ biến hơn cho Python (đó là điều quan trọng!), Mũi. mũi giúp đơn giản hóa và mở rộng khung công tác nhỏ nhất (ví dụ, nó có thể tự động tìm mã kiểm tra của bạn và thiết lập PYTHONPATH cho bạn), nhưng nó không được bao gồm trong bản phân phối Python tiêu chuẩn.

Có lẽ bạn nên nhìn vào mũi như nó gợi ý?


3
Có, điều này hoạt động (đối với tôi), nhưng tôi thực sự yêu cầu các hướng dẫn đơn giản nhất mà tôi có thể cung cấp cho người dùng cho mô-đun của mình để khiến họ chạy thử nghiệm. Sửa đổi đường dẫn thực sự có thể là nó, nhưng tôi đang tìm kiếm thứ gì đó đơn giản hơn.
Thiếu tá

4
Vậy con đường trăn của bạn trông như thế nào sau khi bạn làm việc với hàng trăm dự án? Tôi có nên tự đi vào và dọn dẹp con đường của mình không? Nếu vậy đây là một thiết kế đáng ghét!
jeremyjjbrown

11

Tôi đã có cùng một vấn đề, với một thư mục thử nghiệm đơn vị riêng biệt. Từ các đề xuất được đề cập, tôi thêm đường dẫn nguồn tuyệt đối vào sys.path.

Lợi ích của giải pháp sau là, người ta có thể chạy tệp test/test_yourmodule.pymà không cần thay đổi lúc đầu vào thư mục kiểm tra:

import sys, os
testdir = os.path.dirname(__file__)
srcdir = '../antigravity'
sys.path.insert(0, os.path.abspath(os.path.join(testdir, srcdir)))

import antigravity
import unittest

9

nếu bạn chạy "python setup.py Develop" thì gói sẽ nằm trong đường dẫn. Nhưng bạn có thể không muốn làm điều đó bởi vì bạn có thể lây nhiễm cài đặt python hệ thống của bạn, đó là lý do tại sao các công cụ như virtualenvbuildout tồn tại.


7

Giải pháp / Ví dụ cho mô-đun unittest Python

Cho cấu trúc dự án sau:

ProjectName
 ├── project_name
 |    ├── models
 |    |    └── thing_1.py
 |    └── __main__.py
 └── test
      ├── models
      |    └── test_thing_1.py
      └── __main__.py

Bạn có thể chạy dự án của bạn từ thư mục gốc với python project_name, gọi ProjectName/project_name/__main__.py.


Để chạy thử nghiệm của bạn với python test, chạy hiệu quảProjectName/test/__main__.py , bạn cần làm như sau:

1) Biến test/modelsthư mục của bạn thành một gói bằng cách thêm một __init__.pytập tin. Điều này làm cho các trường hợp thử nghiệm trong thư mục con có thể truy cập từ testthư mục cha .

# ProjectName/test/models/__init__.py

from .test_thing_1 import Thing1TestCase        

2) Sửa đổi đường dẫn hệ thống của bạn test/__main__.pyđể bao gồm project_namethư mục.

# ProjectName/test/__main__.py

import sys
import unittest

sys.path.append('../project_name')

loader = unittest.TestLoader()
testSuite = loader.discover('test')
testRunner = unittest.TextTestRunner(verbosity=2)
testRunner.run(testSuite)

Bây giờ bạn có thể nhập thành công những thứ từ project_nametrong thử nghiệm của bạn.

# ProjectName/test/models/test_thing_1.py    

import unittest
from project_name.models import Thing1  # this doesn't work without 'sys.path.append' per step 2 above

class Thing1TestCase(unittest.TestCase):

    def test_thing_1_init(self):
        thing_id = 'ABC'
        thing1 = Thing1(thing_id)
        self.assertEqual(thing_id, thing.id)

5

Sử dụng setup.py developđể làm cho thư mục làm việc của bạn là một phần của môi trường Python đã cài đặt, sau đó chạy thử nghiệm.


Điều này giúp tôi invalid command 'develop'và tùy chọn này không được đề cập nếu tôi yêu cầu setup.py --help-commands. Có cần phải có một cái gì đó trong setup.pychính nó để làm việc này?
Thiếu tá

Đó là OK - vấn đề là tôi đã thiếu một import setuptoolstừ tôi setup.pytập tin. Nhưng tôi đoán điều đó sẽ cho thấy rằng điều này sẽ không hoạt động mọi lúc cho các mô-đun của người khác.
Thiếu tá

1
Nếu bạn có pip , bạn có thể sử dụng gói đó để cài đặt gói của mình ở chế độ "có thể chỉnh sửa" : pip install -e .Điều này cũng thêm gói vào môi trường Python mà không cần sao chép nguồn, cho phép bạn tiếp tục chỉnh sửa gói ở nơi nó nằm.
Eric Smith

pip install -e .cũng chính xác như vậy python setup.py develop, nó chỉ giúp bạn setup.pysử dụng setuptools ngay cả khi nó không thực sự hoạt động, vì vậy nó hoạt động theo cách nào đó.
Carl Meyer

5

Nếu bạn sử dụng Mã VS và các thử nghiệm của bạn được đặt ở cùng cấp độ với dự án của bạn thì việc chạy và gỡ lỗi mã của bạn sẽ không hoạt động. Những gì bạn có thể làm là thay đổi tệp launch.json của bạn:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python",
            "type": "python",
            "request": "launch",
            "stopOnEntry": false,
            "pythonPath": "${config:python.pythonPath}",
            "program": "${file}",
            "cwd": "${workspaceRoot}",
            "env": {},
            "envFile": "${workspaceRoot}/.env",
            "debugOptions": [
                "WaitOnAbnormalExit",
                "WaitOnNormalExit",
                "RedirectOutput"
            ]
        }    
    ]
}

Dòng chính ở đây là envFile

"envFile": "${workspaceRoot}/.env",

Trong thư mục gốc của dự án, hãy thêm tệp .env

Bên trong tệp .env của bạn thêm đường dẫn vào thư mục gốc của dự án. Điều này sẽ tạm thời thêm

PYTHONPATH = C: \ CỦA BẠN \ PYTHON \ DỰ ÁN \ ROOT_DIRECTORY

đường dẫn đến dự án của bạn và bạn sẽ có thể sử dụng các bài kiểm tra đơn vị gỡ lỗi từ Mã VS


5

Tôi nhận thấy rằng nếu bạn chạy giao diện dòng lệnh nhỏ nhất từ ​​thư mục "src" của mình, thì nhập sẽ hoạt động chính xác mà không cần sửa đổi.

python -m unittest discover -s ../test

Nếu bạn muốn đặt nó trong một tệp bó trong thư mục dự án của bạn, bạn có thể làm điều này:

setlocal & cd src & python -m unittest discover -s ../test

5

Tôi đã có cùng một vấn đề trong một thời gian dài. Những gì tôi đã chọn gần đây là cấu trúc thư mục sau đây:

project_path
├── Makefile
├── src
   ├── script_1.py
   ├── script_2.py
   └── script_3.py
└── tests
    ├── __init__.py
    ├── test_script_1.py
    ├── test_script_2.py
    └── test_script_3.py

và trong __init__.pytập lệnh của thư mục kiểm tra, tôi viết như sau:

import os
import sys
PROJECT_PATH = os.getcwd()
SOURCE_PATH = os.path.join(
    PROJECT_PATH,"src"
)
sys.path.append(SOURCE_PATH)

Siêu quan trọng để chia sẻ dự án là Makefile, vì nó thực thi chạy các kịch bản đúng cách. Đây là lệnh mà tôi đã đặt trong Makefile:

run_tests:
    python -m unittest discover .

Makefile quan trọng không chỉ vì lệnh mà nó chạy mà còn vì nó chạy từ đâu . Nếu bạn muốn cd trong các bài kiểm tra và làm python -m unittest discover ., nó sẽ không hoạt động vì init tập lệnh trong unit_tests gọi os.getcwd (), sau đó sẽ trỏ đến đường dẫn tuyệt đối không chính xác (sẽ được thêm vào sys.path và bạn sẽ bị mất thư mục nguồn của bạn). Các tập lệnh sẽ chạy vì khám phá tìm thấy tất cả các bài kiểm tra, nhưng chúng sẽ không chạy đúng. Vì vậy, Makefile là có để tránh phải nhớ vấn đề này.

Tôi thực sự thích cách tiếp cận này vì tôi không phải chạm vào thư mục src của mình, kiểm tra đơn vị hoặc các biến môi trường của tôi và mọi thứ đều chạy trơn tru.

Hãy cho tôi biết nếu các bạn thích nó.

Hy vọng rằng sẽ giúp,


4

Sau đây là cấu trúc dự án của tôi:

ProjectFolder:
 - project:
     - __init__.py
     - item.py
 - tests:
     - test_item.py

Tôi thấy tốt hơn để nhập trong phương thức setUp ():

import unittest
import sys    

class ItemTest(unittest.TestCase):

    def setUp(self):
        sys.path.insert(0, "../project")
        from project import item
        # further setup using this import

    def test_item_props(self):
        # do my assertions

if __name__ == "__main__":
    unittest.main()

4

Cách thông thường để thực sự chạy thử nghiệm là gì

Tôi sử dụng Python 3.6.2

cd new_project

pytest test/test_antigravity.py

Để cài đặt pytest :sudo pip install pytest

Tôi đã không đặt bất kỳ biến đường dẫn nào và việc nhập của tôi không thất bại với cùng cấu trúc dự án "thử nghiệm".

Tôi đã nhận xét những thứ này: if __name__ == '__main__'như thế này:

test_antigravity.py

import antigravity

class TestAntigravity(unittest.TestCase):

    def test_something(self):

        # ... test stuff here


# if __name__ == '__main__':
# 
#     if __package__ is None:
# 
#         import something
#         sys.path.append(path.dirname(path.dirname(path.abspath(__file__))))
#         from .. import antigravity
# 
#     else:
# 
#         from .. import antigravity
# 
#     unittest.main()

4

Có thể sử dụng trình bao bọc chạy được chọn hoặc tất cả các bài kiểm tra.

Ví dụ:

./run_tests antigravity/*.py

hoặc để chạy tất cả các bài kiểm tra đệ quy sử dụng globalbing ( tests/**/*.py) (enable by shopt -s globstar).

Về cơ bản, trình bao bọc có thể sử dụng argparseđể phân tích các đối số như:

parser = argparse.ArgumentParser()
parser.add_argument('files', nargs='*')

Sau đó tải tất cả các bài kiểm tra:

for filename in args.files:
    exec(open(filename).read())

sau đó thêm chúng vào bộ thử nghiệm của bạn (sử dụng inspect):

alltests = unittest.TestSuite()
for name, obj in inspect.getmembers(sys.modules[__name__]):
    if inspect.isclass(obj) and name.startswith("FooTest"):
        alltests.addTest(unittest.makeSuite(obj))

và chạy chúng:

result = unittest.TextTestRunner(verbosity=2).run(alltests)

Kiểm tra ví dụ này để biết thêm chi tiết.

Xem thêm: Làm thế nào để chạy tất cả các bài kiểm tra đơn vị Python trong một thư mục?


4

Python 3+

Thêm vào @Pierre

Sử dụng unittestcấu trúc thư mục như thế này:

new_project
├── antigravity
   ├── __init__.py         # make it a package
   └── antigravity.py
└── test
    ├── __init__.py         # also make test a package
    └── test_antigravity.py

Để chạy mô-đun thử nghiệm test_antigravity.py:

$ cd new_project
$ python -m unittest test.test_antigravity

Hoặc một TestCase

$ python -m unittest test.test_antigravity.GravityTestCase

Bắt buộc đừng quên __init__.pyngay cả khi trống nếu không sẽ không hoạt động.


2

Bạn không thể nhập từ thư mục cha mà không có một số voodoo. Đây là một cách khác hoạt động với ít nhất Python 3.6.

Đầu tiên, hãy kiểm tra tệp / bối cảnh với nội dung sau:

import sys
import os
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))

Sau đó, có lần nhập sau trong tệp test / test_antigravity.py:

import unittest
try:
    import context
except ModuleNotFoundError:
    import test.context    
import antigravity

Lưu ý rằng lý do cho mệnh đề ngoại trừ thử này là

  • nhập test.context không thành công khi chạy với "python test_antigravity.py" và
  • bối cảnh nhập thất bại khi chạy với "python -m unittest" từ thư mục new_project.

Với mánh khóe này cả hai đều làm việc.

Bây giờ bạn có thể chạy tất cả các tệp thử nghiệm trong thư mục thử nghiệm với:

$ pwd
/projects/new_project
$ python -m unittest

hoặc chạy một tệp thử nghiệm riêng lẻ với:

$ cd test
$ python test_antigravity

Ok, nó không đẹp hơn nhiều so với nội dung của ngữ cảnh trong test_antigravity.py, nhưng có lẽ một chút. Đề nghị được chào đón.


2

Nếu bạn có nhiều thư mục trong thư mục kiểm tra của mình, thì bạn phải thêm vào mỗi thư mục một __init__.pytệp.

/home/johndoe/snakeoil
└── test
    ├── __init__.py        
    └── frontend
        └── __init__.py
        └── test_foo.py
    └── backend
        └── __init__.py
        └── test_bar.py

Sau đó, để chạy mọi bài kiểm tra cùng một lúc, hãy chạy:

python -m unittest discover -s /home/johndoe/snakeoil/test -t /home/johndoe/snakeoil

Nguồn: python -m unittest -h

  -s START, --start-directory START
                        Directory to start discovery ('.' default)
  -t TOP, --top-level-directory TOP
                        Top level directory of project (defaults to start
                        directory)

1

Kịch bản BASH này sẽ thực thi thư mục kiểm tra không đáng tin nhất python từ bất kỳ đâu trong hệ thống tệp, bất kể bạn đang ở thư mục làm việc nào.

Điều này hữu ích khi ở trong thư mục ./srchoặc ./examplelàm việc và bạn cần kiểm tra đơn vị nhanh:

#!/bin/bash

this_program="$0"
dirname="`dirname $this_program`"
readlink="`readlink -e $dirname`"

python -m unittest discover -s "$readlink"/test -v

Không cần một test/__init__.py tập tin để gánh nặng gói / bộ nhớ của bạn trong quá trình sản xuất.


1

Cách này sẽ cho phép bạn chạy các kịch bản thử nghiệm từ bất cứ nơi nào bạn muốn mà không phải loay hoay với các biến hệ thống từ dòng lệnh.

Điều này thêm thư mục dự án chính vào đường dẫn python, với vị trí được tìm thấy liên quan đến chính tập lệnh, không liên quan đến thư mục làm việc hiện tại.

import sys, os

sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.realpath(__file__))))

Thêm vào đầu tất cả các kịch bản thử nghiệm của bạn. Điều đó sẽ thêm thư mục dự án chính vào đường dẫn hệ thống, do đó, bất kỳ mô-đun nhập nào hoạt động từ đó sẽ hoạt động. Và nó không thành vấn đề khi bạn chạy thử nghiệm từ đâu.

Rõ ràng bạn có thể thay đổi tệp project_path_hack để phù hợp với vị trí thư mục dự án chính của bạn.


0

Nếu bạn đang tìm kiếm một giải pháp chỉ dòng lệnh:

Dựa trên cấu trúc thư mục sau (tổng quát với thư mục nguồn chuyên dụng):

new_project/
    src/
        antigravity.py
    test/
        test_antigravity.py

Windows : (trong new_project)

$ set PYTHONPATH=%PYTHONPATH%;%cd%\src
$ python -m unittest discover -s test

Xem câu hỏi này nếu bạn muốn sử dụng này trong một đợt lặp.

Linux : (trong new_project)

$ export PYTHONPATH=$PYTHONPATH:$(pwd)/src  [I think - please edit this answer if you are a Linux user and you know this]
$ python -m unittest discover -s test

Với phương pháp này, cũng có thể thêm nhiều thư mục vào PYTHONPATH nếu cần thiết.


0

Bạn thực sự nên sử dụng công cụ pip.

Sử dụng pip install -e .để cài đặt gói của bạn trong chế độ phát triển. Đây là một thực hành rất tốt, được đề xuất bởi pytest (xem tài liệu thực hành tốt của họ , nơi bạn cũng có thể tìm thấy hai bố cục dự án để làm theo).


Tại sao downvote câu trả lời này? Tôi đã đọc câu trả lời được chấp nhận và mặc dù nó không tệ, nhưng pytestcách tốt hơn để chạy thử nghiệm, bởi vì đầu ra giao diện điều khiển bạn nhận được, có màu, với thông tin theo dõi ngăn xếp và thông tin lỗi xác nhận chi tiết.
aliopi
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.