2010-01-18 21 views
33

Gần đây tôi đã bắt đầu sử dụng git và cũng bắt đầu thử nghiệm đơn vị (sử dụng mô-đun unittest của Python). Tôi muốn chạy thử nghiệm của mình mỗi lần tôi cam kết và chỉ cam kết nếu họ vượt qua.Cam kết chỉ trong git nếu các thử nghiệm vượt qua

Tôi đoán mình cần sử dụng pre-commit trong /hooks và tôi đã quản lý để chạy thử nghiệm, nhưng dường như tôi không thể tìm cách dừng cam kết nếu kiểm tra không thành công. Tôi đang chạy thử nghiệm với make test, do đó đang chạy python3.1 foo.py --test. Có vẻ như tôi không có điều kiện xuất cảnh khác cho dù các bài kiểm tra vượt qua hay thất bại, nhưng tôi có thể đang tìm kiếm sai chỗ.

Chỉnh sửa: Đây có phải là điều gì đó không phổ biến mà tôi muốn làm ở đây không? Tôi đã nghĩ rằng đó là yêu cầu chung ...

Chỉnh sửa2: Chỉ trong trường hợp mọi người không thể bị làm phiền khi đọc nhận xét, vấn đề là unittest.TextTestRunner không thoát với trạng thái khác 0 bộ kiểm thử thành công hay không. Để bắt được nó, tôi đã làm:

result = runner.run(allTests) 
if not result.wasSuccessful(): 
    sys.exit(1) 
+0

câu hỏi gần đây trên SO đi đến đầu truy vấn của Google khá nhanh; và sau đó thả xuống trong bảng xếp hạng một cách nhanh chóng là tốt. Việc hỏi một câu hỏi và 5 phút sau đó không phải là điều bình thường khi nó trở thành hit hàng đầu của Google; nhưng trong một tuần, bạn có thể khó tìm thấy nó hơn. –

+0

@Brian Ah, đủ công bằng. Tôi không nhận ra rằng Google đã làm việc như thế. – Skilldrick

+0

Lệnh 'python3.1 foo.py --test' của bạn có trả lại trạng thái thoát khác không? Liệu 'make' có trả lại trạng thái thoát khác không nếu bạn chạy nó theo cách thủ công? Và nội dung của cái móc 'tiền cam kết' của bạn là gì? –

Trả lời

30

Tôi sẽ kiểm tra để đảm bảo rằng mỗi bước trên đường đi, tập lệnh của bạn sẽ trả về mã thoát không khác về lỗi. Kiểm tra xem liệu python3.1 foo.py --test của bạn có trả về mã thoát không khác nếu thử nghiệm không thành công. Kiểm tra để đảm bảo lệnh make test của bạn trả lại mã thoát khác. Và cuối cùng, hãy kiểm tra xem bản thân móc pre-commit của bạn có trả lại mã thoát khác không về lỗi không.

Bạn có thể kiểm tra mã thoát khác 0 bằng cách thêm || echo $? vào cuối lệnh; sẽ in ra mã thoát nếu lệnh thất bại.

Ví dụ sau đây làm việc cho tôi (tôi đang chuyển hướng stderr để /dev/null để tránh bao gồm quá nhiều đầu ra không liên quan ở đây):

$ python3.1 test.py 2>/dev/null || echo $? 
1 
$ make test 2>/dev/null || echo $? 
python3.1 test.py 
2 
$ .git/hooks/pre-commit 2>/dev/null || echo $? 
python3.1 test.py 
1 

test.py:

import unittest 

class TestFailure(unittest.TestCase): 
    def testFail(self): 
     assert(False) 

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

Makefile:

test: 
    python3.1 test.py 

.git/hooks/pre-commit:

#!/bin/sh 
make test || exit 1 

Lưu ý || exit 1. Điều này là không cần thiết nếu make test là lệnh cuối cùng trong móc, vì trạng thái thoát của lệnh cuối cùng sẽ là trạng thái thoát của tập lệnh. Nhưng nếu bạn có kiểm tra sau này trong móc pre-commit của bạn, sau đó bạn cần phải chắc chắn rằng bạn thoát với một lỗi; nếu không, lệnh thành công ở cuối móc sẽ khiến tập lệnh của bạn thoát với trạng thái là 0.

+0

Rất thú vị. +1 – VonC

+2

@Brian - Cảm ơn. Vấn đề là tôi đã chạy thử nghiệm của tôi với 'unittest.TextTestRunner' không thoát ra với trạng thái khác 0. Tôi đã phải làm 'nếu không result.wasSuccessful(): sys.exit (1)'. – Skilldrick

+2

Một vấn đề khác ở đây là thử nghiệm đang chạy trên bản sao làm việc của bản sửa đổi và không phải là giai đoạn. Nếu bạn luôn cam kết tất cả các thay đổi, đây không phải là vấn đề, nhưng nếu bạn thực hiện các cam kết từng phần, thì các cam kết trung gian của bạn có thể không vượt qua bài kiểm tra (Xem: [http://stackoverflow.com/questions/2412450/git-pre-commit -hook-changed-added-files/3068990 # 3068990] – LarryH

6

Bạn có thể phân tích cú pháp kết quả của phiên thử nghiệm python và đảm bảo thoát khỏi móc trước của bạn bằng trạng thái khác không?

Móc phải thoát với trạng thái khác 0 sau khi phát hành thông báo thích hợp nếu muốn dừng cam kết.

Vì vậy, nếu tập lệnh python của bạn không trả lại trạng thái thích hợp vì bất kỳ lý do nào, bạn cần xác định trạng thái đó trực tiếp từ tập lệnh móc pre-commit.
Điều đó sẽ đảm bảo cam kết không tiến lên nếu các thử nghiệm không thành công.
(hoặc bạn có thể gọi từ móc một wrapper python mà sẽ gọi các bài kiểm tra, và đảm bảo một sys.exit(exit_status) theo kết quả kiểm tra).

+0

http://www.heikkitoivonen.net/blog/2009/01/28/pexpect-and-inconsistent-exit-status/ có thể có liên quan quá tại đây – VonC

+2

Điều thú vị là, trong Git Book, Scott Chacon thực hiện một điều tương tự (phân tích cú pháp kết quả kiểm tra), với Ruby: http://book.git-scm.com/5_git_hooks.html – Skilldrick

+0

Cảm ơn sự giúp đỡ của bạn với điều này. Bạn đã đúng rằng vấn đề là với tình trạng thích hợp không được trả lại. Một phần của vấn đề là kỹ năng vỏ noobish của tôi - Tôi đã không hoàn toàn có hang chưa! – Skilldrick

0

Một lựa chọn khác, nếu bạn không muốn xử lý bằng tay của pre-cam kết: Có đẹp công cụ để chạy thử nghiệm và kiểm tra cú pháp cho Python, Ruby và vân vân: github/overcommit

Các vấn đề liên quan