Làm cách nào tôi có thể sử dụng các bài kiểm tra đơn vị và TDD để kiểm tra một ứng dụng chủ yếu dựa trên các hoạt động CRUD của cơ sở dữ liệu?


22

Tại nơi làm việc, một trong những dự án của tôi chủ yếu là lấy dữ liệu được truyền từ máy khách bên ngoài và duy trì nó trong cơ sở dữ liệu. Đó là một ứng dụng doanh nghiệp Java sử dụng JPA và hầu hết logic của chúng tôi xoay quanh các hoạt động CRUD.

Phần lớn các lỗi của chúng tôi liên quan đến JPA bằng cách này hay cách khác.

  • Ví dụ 1: Nếu bạn nhấp vào nút lưu hai lần, JPA có thể cố gắng chèn cùng một thực thể vào cơ sở dữ liệu lần thứ hai, gây ra vi phạm khóa chính.
  • Ví dụ 2: Bạn truy xuất một thực thể từ cơ sở dữ liệu, chỉnh sửa nó và cố gắng cập nhật dữ liệu của nó. JPA có thể cố gắng tạo một phiên bản mới thay vì cập nhật phiên bản cũ.

Thường thì giải pháp là cần thêm / xóa / thay đổi chú thích JPA. Những lần khác, nó phải làm với việc sửa đổi logic DAO.

Tôi không thể tìm ra cách lấy niềm tin vào mã của chúng tôi bằng các bài kiểm tra đơn vị và TDD. Tôi không chắc liệu đó có phải là do các bài kiểm tra đơn vị và TDD không phù hợp hay không, nếu tôi tiếp cận vấn đề sai.

Các bài kiểm tra đơn vị có vẻ không phù hợp vì tôi chỉ có thể phát hiện ra những vấn đề này khi chạy và tôi cần triển khai đến một máy chủ ứng dụng để tái tạo các vấn đề. Thông thường cơ sở dữ liệu cần phải được tham gia mà tôi cho là nằm ngoài định nghĩa của kiểm tra đơn vị: Đây là các kiểm tra tích hợp.

TDD có vẻ như không phù hợp vì vòng lặp phản hồi triển khai + kiểm tra quá chậm nên khiến tôi rất không hiệu quả. Vòng lặp phản hồi triển khai + kiểm tra mất hơn 3 phút và đó chỉ là khi tôi chạy thử nghiệm cụ thể về mã tôi đang viết. Để chạy tất cả các bài kiểm tra tích hợp mất hơn 30 phút.

Có mã bên ngoài khuôn này và tôi luôn kiểm tra đơn vị bất cứ khi nào tôi có thể. Nhưng phần lớn các lỗi của chúng tôi và thời gian chìm lớn nhất luôn liên quan đến JPA hoặc cơ sở dữ liệu.


Có một câu hỏi khác tương tự , nhưng nếu tôi làm theo lời khuyên, tôi sẽ gói phần không ổn định nhất trong mã của mình (JPA) và kiểm tra mọi thứ trừ nó. Trong bối cảnh câu hỏi của tôi, tôi sẽ ở trong tình trạng tồi tệ tương tự. Bước tiếp theo sau khi gói JPA là gì? IMO câu hỏi đó (có lẽ) là một bước để trả lời câu hỏi của tôi, nhưng không phải là một câu trả lời cho nó.


4
Những gì bạn đang làm về cơ bản là kiểm thử tích hợp, vì bạn phải thiết lập cơ sở dữ liệu để thực sự kiểm tra. Tôi có thể tưởng tượng rằng một mô-đun sẽ dựa vào các mô-đun khác để làm cho nó thậm chí giống như thử nghiệm tích hợp hơn. Tôi sẽ thay đổi câu hỏi bạn có để áp dụng phương pháp TDD vào ứng dụng của bạn.
Được thông báo vào

@randomA đúng, tôi đã chỉnh sửa câu hỏi của mình để nói rõ ràng điều đó. Tôi không hiểu tại sao bạn lại khuyên tôi nên thay đổi câu hỏi. Bạn có thể xây dựng? Tôi muốn giữ một phần đơn vị thử nghiệm trong đó bởi vì tôi muốn thay được viết unit tests hơn xét nghiệm hội nhập (mặc dù tôi biết rằng unit testing != TDD)
Daniel Kaplan

Không có gì đặc biệt, chỉ cần đặt TDD ở đó. Nếu bạn có bài kiểm tra đơn vị ở đó, thì nhiều người sẽ nghĩ bạn không hiểu điều gì, v.v .. không tốt cho bạn ..
thông báo vào


Câu trả lời:


7

Một tùy chọn là sử dụng cơ sở dữ liệu kiểm tra trong bộ nhớ như H2 ; nó có xu hướng nhanh hơn khoảng 10 lần so với cơ sở dữ liệu sử dụng đĩa tiêu chuẩn và với thời gian khởi động / xé nhỏ hơn.

Việc nó có giúp ích hay không phần lớn phụ thuộc vào việc các vấn đề JPA mà bạn đang gặp có đủ chung để chúng vẫn thất bại trên các cơ sở dữ liệu khác nhau hay không. Không có nhiều điểm chạy thử nghiệm nhanh hơn nếu họ bỏ lỡ phần lớn các vấn đề.

Nhưng nếu bạn có thể thực hiện 10 lần chạy với H2 cho mỗi lần với toàn bộ hệ thống, nó có thể được đền đáp.


Đó là một suy nghĩ tốt, nhưng tôi vẫn phải triển khai đến máy chủ ứng dụng, AFAIK. Đó là rất nhiều trong hơn 3 phút. Điều đó nói rằng, nó chắc chắn đáng làm. Nhưng vẫn khó có thể tưởng tượng việc chạy các bài kiểm tra thường xuyên như tôi sẽ chạy các bài kiểm tra đơn vị và do đó có vẻ không hiệu quả khi phát triển bằng TDD.
Daniel Kaplan

1
Tôi nghĩ rằng thường có những cách xung quanh yêu cầu đó (ví dụ: docs.oracle.com/middleware/1212/toplink/TLADG/testingjpa.htm ). Mặc dù cơ hội khá cao là làm việc nhiều hơn là hợp lý; một lựa chọn khác là có được một số máy chủ thử nghiệm mạnh hơn và chạy mọi thứ song song.
soru

1
@tieTYT Bằng chứng khái niệm của riêng tôi với đơn vị hsqldb đang thử nghiệm một ứng dụng web thô sơ trên github: testsWithHsqldb - các thử nghiệm đơn vị không cần ứng dụng được triển khai.

3

Cơ sở dữ liệu có thể rất dễ dàng để kiểm tra đơn vị - bạn cần các thủ tục và giao dịch được lưu trữ.

Đây là những gì Microsoft nói về kiểm tra đơn vị cơ sở dữ liệu . Bạn cũng có thể chạy thử nghiệm đơn vị dựa trên cơ sở dữ liệu, viết thử nghiệm của mình bằng Java hoặc C # bằng cách thiết lập kết nối DB, bắt đầu giao dịch, viết bất kỳ dữ liệu nào bạn muốn sử dụng để thử nghiệm vào DB, chạy thử nghiệm và sau đó quay lại. Không có thiệt hại cho DB nếu bạn đang sử dụng một DB mà bạn cũng đã triển khai và bạn nhận được các thử nghiệm cách ly hoàn toàn.

Hy vọng điều này có thể cung cấp cho bạn một cái nhìn sâu sắc làm thế nào để làm điều đó trong khuôn khổ của bạn.


Như tôi đã nói, "Phần lớn các lỗi của chúng tôi liên quan đến JPA bằng cách này hay cách khác.", Tôi nghĩ rằng lời khuyên của bài viết sẽ bỏ lỡ tất cả những lỗi đó. Ngoài ra, nếu bạn coi các thử nghiệm Java / C # này vẫn là các thử nghiệm đơn vị, chúng tôi đã có các định nghĩa rất khác nhau. Tôi nghĩ rằng đây là lời khuyên tốt nói chung, nhưng có vẻ như sẽ mất rất nhiều thời gian để triển khai và chạy bộ phần mềm và do đó không có lợi cho TDD. Bạn có không đồng ý không?
Daniel Kaplan

Chúng tôi đã từng chạy các bài kiểm tra đơn vị DB cho SQL của mình, nhưng sau đó tất cả chúng đều ở dạng sprocs. Trong khi bạn có thể đơn vị thư mục kiểm tra sql từ thủ tục sql khác, khuôn khổ đơn vị thử nghiệm của chúng tôi là MSTest nên nó làm cho tinh thần để chạy chúng từ đó (hey, chúng tôi đã nhận ve xanh trong xây dựng máy chủ đó là những yếu tố quan trọng nhất). Nếu bạn luôn có DB (và dù sao chúng tôi cũng đã thử nghiệm int) thì có thể dễ dàng tải lên tất cả mã sql và chạy tất cả các bài kiểm tra đơn vị trên máy chủ bản dựng. Đôi khi bạn chỉ cần thực dụng về những điều này.
gbjbaanb

Tôi không nghĩ bạn đã trả lời câu đầu tiên của tôi.
Daniel Kaplan

tốt, chỉ cần sử dụng jpa-đơn vị sau đó. Tôi không thể trả lời mã JPA của bạn hoạt động như thế nào (hoặc không), chỉ cần cố gắng cung cấp cho bạn một số ý tưởng về việc thử nghiệm sql đó trong db.
gbjbaanb

3

Những người khác đã trả lời với "Mock out DB của bạn!" - nhưng điểm quan trọng trong việc loại bỏ lớp DB của bạn là gì nếu bạn thực sự cần kiểm tra xem nó tương tác với mã của bạn như thế nào?

Những gì bạn đang tìm kiếm là kiểm tra tích hợp và / hoặc kiểm tra giao diện người dùng tự động. Bạn đã đề cập rằng vấn đề xảy ra khi:

*If you click the save button twice*

Cách duy nhất để kiểm tra điều này là viết một bài kiểm tra UI tự động để nhấp vào nút hai lần. Có thể kiểm tra Selenium.

Bạn cũng có thể sẽ cần một DB thử nghiệm đơn vị và cho các thử nghiệm của bạn hướng nó tới đó. Một nỗi đau để duy trì nhưng chào mừng bạn đến với TDD trong thế giới thực.


điều này đọc giống như một câu nói hay hơn là một câu trả lời
gnat

Tôi đã trả lời câu hỏi ba lần - kiểm tra tích hợp, kiểm tra GUI và / hoặc DB kiểm tra đơn vị. Vâng, đó là một chút giận dữ, bây giờ tôi sẽ chỉnh sửa nó thành một số vấn đề về sự tỉnh táo.
Rocklan

1
"Cách duy nhất để kiểm tra điều này là viết một bài kiểm tra UI tự động để nhấp vào nút hai lần. Có thể kiểm tra Selenium." Trong các tình huống như vậy, phần phụ trợ tốt hơn nên ngăn điều đó xảy ra, nếu không thì UI sẽ có quyền truy cập trực tiếp vào cơ sở dữ liệu.
Daniel Kaplan

0

Trong ví dụ bạn đưa ra trong câu hỏi của mình, bạn không thể kiểm tra đơn vị / TDD theo cách của bạn trong tình huống nhấp vào nút hai lần để gây ra lỗi rất dễ dàng. Nhưng những gì bạn có thể kiểm tra đơn vị là trong mã được gọi khi bạn nhấp vào nút, nếu bạn nhận được một ngoại lệ từ lớp liên tục, bạn xử lý nó một cách thích hợp (bằng cách loại bỏ lớp liên tục hoặc bằng cách sử dụng cơ sở dữ liệu trong bộ nhớ như đã được đề xuất trong các câu trả lời khác) - bằng cách suy nghĩ lại hoặc hiển thị lỗi hoặc bất cứ điều gì.

Bạn nói đúng rằng TDD có thể bắt đầu bị hỏng khi bạn cần thực hiện các bài kiểm tra không phù hợp với bài kiểm tra đơn vị (tức là kiểm tra tích hợp / hệ thống) - điều này hình thành khá nhiều cuộc thảo luận trong "Is TDD gần đây Đã chết?" các cuộc tranh luận giữa Kent Beck, Martin Fowler và David Heinemeier Hansson: http://martinfowler.com/articles/is-tdd-dead/

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.