Là đơn vị HSQLDB kiểm tra một mô hình chống?


9

HSQLDB là tuyệt vời. Nó (cũng) có chế độ nhúng (không cần máy chủ chuyên dụng), cho phép tạo mẫu nhanh các nội dung như Proof of Conception, và nó cũng có thể tuyệt vời trong các ứng dụng sẵn sàng sản xuất, vì lưu trữ dữ liệu đơn giản và nhanh chóng.

Tuy nhiên, ít nhất 90% các dự án tôi đã làm trong những năm qua, nếu chúng xử lý bằng bất kỳ cách nào với cơ sở dữ liệu SQL, chắc chắn chúng sẽ có các bài kiểm tra đơn vị sử dụng HSQLDB nhúng.

Chắc chắn, các dự án này (sử dụng cấu trúc Maven tiêu chuẩn hầu hết thời gian), có rất nhiều "thử nghiệm đơn vị" (hoặc, ít nhất, một số loại thử nghiệm, nhưng nằm trong khu vực "thử nghiệm đơn vị" của dự án (như "src / test / java")) sử dụng một hoặc nhiều phiên bản nhúng của HSQLDB để thực hiện một số thao tác CRUD và kiểm tra kết quả.

Câu hỏi của tôi là: đây có phải là một mô hình chống? Có phải thực tế là HSQLDB dễ tích hợp và máy chủ nhúng rất nhẹ khiến nó có thể bị bỏ qua như là "mô phỏng" của một cơ sở dữ liệu thực tế, khi không nên như vậy? Các thử nghiệm như vậy không nên được đối xử giống như các thử nghiệm tích hợp (vì mỗi thử nghiệm này bao gồm "cái gì đó" sự tích hợp của "cái gì đó" với một máy chủ cơ sở dữ liệu)? Hoặc tôi đang thiếu một cái gì đó trong định nghĩa "kiểm tra đơn vị" và chúng ta có thể nói rằng việc sử dụng HSQLDB như thế này chỉ đơn giản là tuân thủ "giả định phụ thuộc và chỉ kiểm tra phần đơn vị" của định nghĩa "kiểm tra đơn vị"?


3
Đây không phải là chế nhạo áp dụng cho lớp Cơ sở dữ liệu sao? Tôi sẽ không nói rằng đó là một mô hình chống miễn là nó là một cách đơn giản và phù hợp để có được các mô-đun phụ thuộc vào nó được thử nghiệm theo đơn vị.
Kilian Foth

2
@KilianFoth có nhưng nó vẫn bị chế giễu khi "mock" (db) thực sự đóng vai trò tích cực trong quá trình thử nghiệm? Ví dụ: khi bạn có một lớp với một số phụ thuộc (bắt buộc để khởi tạo lớp đó), nếu bạn muốn kiểm tra đơn vị lớp đó, bạn chế giễu sự phụ thuộc đó, nhưng sau đó bạn chỉ cần kiểm tra các phương thức của lớp, bạn không quan tâm hơn nữa về sự phụ thuộc bị chế giễu, nó không có vai trò lớn như vậy trong toàn bộ bài kiểm tra đơn vị của lớp, vì HSQLDB có trong các bài kiểm tra đơn vị này ...
Shivan Dragon


1
@gnat tốt, cá nhân tôi thấy câu hỏi khác giống như "làm thế nào để kiểm tra đơn vị công cụ ở lớp truy cập dữ liệu trên - chúng ta có nên giả định lớp truy cập dữ liệu hay không", trong khi của tôi là "làm thế nào để tôi kiểm tra đơn vị tại chính lớp truy cập dữ liệu, có phải HSQLD và giống như một cách hợp lệ để chế giễu mọi thứ không? "...
Shivan Dragon

Câu trả lời:


8

Tôi xem xét việc sử dụng một cái gì đó như HSQLDB (hoặc DBUnit) khi kiểm tra DAO của tôi như một bước cần thiết để đảm bảo chất lượng đối với mã tôi viết khi chạm vào lớp dữ liệu. Như đã chỉ ra, nó không phải là một giải pháp chống đạn nhưng kết hợp với phương ngữ của nó, nó có thể bao gồm một phần hợp lý trong các trường hợp của bạn.

Quan điểm duy nhất của tôi sẽ là: hãy cẩn thận khi chúng ta nói về các bài kiểm tra đơn vị . Khi tôi kiểm tra một lớp tương tác với một thành phần bên ngoài nằm ngoài tầm kiểm soát của tôi (nghĩa là nó có thể tạo ra hành vi không xác định), tôi coi nó tự động như một thử nghiệm tích hợp.

Giả sử rằng bạn đã tìm ra logic nơi bạn tương tác trực tiếp với kho dữ liệu của bạn (thông qua trình điều khiển JDBC, ORM, v.v.) trong một lớp cụ thể được ẩn bởi một giao diện, một bài kiểm tra đơn vị thích hợp cho DAO của bạn sẽ được phát triển bằng cách chuyển đến nó một triển khai giả định cụ thể của giao diện trả về một tập hợp các giá trị nổi tiếng mà bạn sẽ kiểm tra nó.


5

IMO:

  • Nếu một bài kiểm tra yêu cầu DB, thì đó không phải là bài kiểm tra đơn vị. Nó là thử nghiệm tích hợp hoặc chấp nhận.
  • Để tránh sự cần thiết phải sử dụng DB trong thử nghiệm, tôi nên tuân theo nguyên tắc điều khiển bằng cách sử dụng phép tiêm phụ thuộc (hoặc bộ định vị dịch vụ).
  • Nếu tôi cần kiểm tra một cái gì đó với DB, tôi nên tạo một VM với cơ sở dữ liệu thực tế (với dữ liệu giả hoặc dữ liệu thực, tùy thuộc vào nhiệm vụ). VagrantDocker là những công cụ tuyệt vời cho công việc.
  • Mocking DB là một thực hành xấu. Nó cũng giống như làm sai (chế nhạo DB) và sau đó làm lại đúng (làm cho nó hoạt động với DB thực).
  • Nó là OK cho các dự án bằng chứng khái niệm, nhưng sau đó nó được theo sau bởi làm lại (nếu khái niệm được chứng minh).
  • Hoàn toàn ổn khi sử dụng HSQLDB (hoặc bất cứ điều gì) nếu nó là một công cụ thích hợp cho công việc.

4

Sử dụng cùng một cơ sở dữ liệu cho các bài kiểm tra (đơn vị-) như bạn đang sử dụng trong môi trường sản xuất của mình.

Lý do rất đơn giản: Cơ sở dữ liệu hành xử khác nhau. Mỗi cơ sở dữ liệu có chức năng độc quyền riêng của họ. Ngay cả khi bạn sử dụng lớp ORM để truy cập cơ sở dữ liệu, cơ sở dữ liệu của bạn có thể hoạt động khác đi, cũng hiệu quả.

Tất nhiên, lợi thế của cơ sở dữ liệu nhúng cho các bài kiểm tra đơn vị là bạn không phải cấu hình bất cứ thứ gì. Nhưng cài đặt cơ sở dữ liệu trên mọi máy phát triển và cấu hình nó sẽ được sử dụng cho các bài kiểm tra đơn vị không khó lắm.

Tôi đã có tình huống tương tự trong một dự án một thời gian trước đây. Chúng tôi đã sử dụng JDBC để chạy các câu lệnh SQL trên cơ sở dữ liệu. Khi chúng tôi quyết định viết bài kiểm tra cho ứng dụng của mình, chúng tôi đã sử dụng cơ sở dữ liệu nhúng. Điều đó dẫn đến tình huống một số lỗi không thể được sao chép bằng các bài kiểm tra đơn vị và một số phần của ứng dụng không thể được kiểm tra vì cơ sở dữ liệu nhúng không hỗ trợ các chức năng của cơ sở dữ liệu sản xuất của chúng tôi. Vì vậy, mọi nhà phát triển đã cài đặt cùng một cơ sở dữ liệu mà chúng tôi cũng đã sử dụng trong môi trường sản xuất trên PC để chạy thử nghiệm, hoạt động tốt hơn nhiều.


Đó là rất nhiều trường hợp Oracle mà bạn đang đề xuất cài đặt trong một số môi trường - không hề rẻ chút nào. Đừng quên máy chủ xây dựng.

@MichaelT Tôi biết, nhưng sự thay thế là gì?
Uooo

2
Người ta có thể sử dụng HSQLDB làm việc với một phương ngữ tiên tri (xem sql.syntax_oratrong hsqldb.org/doc/guide/dbproperIES-chapt.html ) - nó không hoàn hảo, nhưng đủ tốt cho hầu hết mọi thứ. Như bạn lưu ý, đây không phải là giải pháp mọi thứ, nhưng nó giải quyết được các vấn đề về nhiều giấy phép cần thiết và cho phép các bản dựng độc lập không phụ thuộc vào dịch vụ khác đang chạy. Một cách tiếp cận khác sẽ là dbunit . Thực sự có sự đánh đổi với mỗi cách tiếp cận.

@MichaelT Oracle là miễn phí để phát triển / thử nghiệm. Vì vậy, không có chi phí để cài đặt một phiên bản Oracle khác để thử nghiệm. Tất nhiên có chi phí cài đặt thêm phần cứng để chạy tất cả các trường hợp đó.
jwenting

2
Tôi sẽ không coi đó là một thử nghiệm đơn vị nếu nó đang truy cập vào một DB không được nhúng
herman

4

Tôi đã tìm thấy & khắc phục một số vấn đề thực sự xấu và tăng tốc đáng kể sự phát triển của tôi bằng cách kiểm tra đối với cơ sở dữ liệu HSQL. Thường thì mức độ thấp nhất của các lớp bộ điều hợp (tức là DAO của bạn) có thể chưa được kiểm tra trong thử nghiệm đơn vị vì khó có thể tách chúng ra khỏi chuyến đi khứ hồi thực tế đến cơ sở dữ liệu trực tiếp. Tôi đã chế nhạo các tạo phẩm của Connection và JDBC trong quá khứ, nhưng nó thực sự khó hơn nhiều so với thử nghiệm đối với cơ sở dữ liệu trong bộ nhớ.

Trong một dự án, tôi đã phát triển và thử nghiệm với HSQL, chạy cục bộ với MySql và triển khai để sản xuất chống lại SQL-Server. Thật đáng ngạc nhiên, nó hoạt động tốt. Vấn đề tích hợp lớn nhất mà tôi gặp phải là do sự hiểu lầm của riêng tôi về thông số kỹ thuật (giây so với mili giây, lol).

Mặc dù khung kiên trì có thể che dấu cơ sở dữ liệu cơ bản (như Hibernate), nhưng chính khung bền vững có thể bổ sung đủ ngữ nghĩa phức tạp để thực hiện nó một cách tách biệt có thể rũ bỏ rất nhiều điều kỳ quặc trước khi bạn tiến hành kiểm tra tích hợp toàn diện.

Hãy xem xét trường hợp bạn đang sử dụng Hibernate hoặc JPA để xây dựng một tập kết quả phức tạp với rất nhiều phép nối. Nếu nó khó chịu và mất nhiều cố gắng, bạn có thể phát triển và kiểm tra nó dựa trên cơ sở dữ liệu trực tiếp. Nhưng bạn cũng có thể phát triển và kiểm tra nó dựa trên cơ sở dữ liệu trong bộ nhớ với ít chi phí hoạt động hơn. Bạn cũng không phải lo lắng về các tập lệnh thiết lập / phân tích cho đồ đạc cơ sở dữ liệu của mình hoặc phối hợp kiểm tra và xây dựng với người khác. Và nếu bạn kiểm tra dựa trên cơ sở dữ liệu trong bộ nhớ, bạn sẽ tận hưởng những lợi ích của việc kiểm tra hồi quy xung quanh, giống như các bài kiểm tra đơn vị khác.

Tôi đã nghe thuật ngữ "Kiểm tra thành phần" cho các thử nghiệm nhiều hơn thử nghiệm đơn vị, nhưng vẫn được thực hiện một cách cô lập.

Các thử nghiệm đơn vị, Thử nghiệm thành phần (nếu đó thực sự là tên của chúng) và Thử nghiệm tích hợp đều cung cấp giá trị. Các nhóm có thể phân phối với nhau hoặc khác (vâng, rất nhiều nhóm không thử nghiệm đơn vị & chỉ dựa vào thử nghiệm Tích hợp), nhưng nếu bạn làm điều đó, bạn sẽ mất đi những lợi ích mà các tầng thử nghiệm khác mang lại.

Trong trường hợp các bài kiểm tra bị cô lập nhờ tích hợp vào bộ nhớ, lợi ích là xác nhận mã nhanh chóng, sau đó hồi quy nhanh - lợi ích của kiểm tra cách ly và không cần cài đặt thêm, giấy phép hoặc phần cứng. Nó cho phép bạn xác thực nhiều cấp mã riêng lẻ hơn so với khi bạn chỉ kiểm tra DAO cho đến khi cơ sở dữ liệu được cung cấp.

Vì vậy, có giá trị thực tế. Điều đó không bắt buộc, nhưng tôi đã hạnh phúc hơn là ít hơn khi tôi thực hiện nó.


3

Tôi đã sử dụng các cách tiếp cận như vậy trong quá khứ, tôi không chắc đây có phải là "chống mẫu" không (một số người cố gắng nâng cao cảm xúc hoặc kinh nghiệm cá nhân của mình theo các quy tắc phổ quát, nhưng tôi không thích cách tiếp cận khác:

  • Đối với kiểm tra đơn vị, kiểm tra đơn vị thực tế không sử dụng những thứ bên ngoài như cơ sở dữ liệu trong bộ nhớ (không thực sự nhẹ nếu bạn so sánh với hashMap hoặc sơ khai sử dụng một số thư viện còn sơ khai). Nếu bạn sử dụng DI và một mẫu đơn giản như Kho lưu trữ hoặc DAO để truy cập dữ liệu của bạn, điều này rất dễ đạt được. Mục tiêu của tôi là có rất nhiều bài kiểm tra đơn vị thực hiện rất nhanh, và với suy nghĩ nhanh chóng, tôi đang suy nghĩ trong bài kiểm tra 3k trong vòng chưa đầy một phút.

  • Đối với thử nghiệm tích hợp, tôi thích sử dụng phần mềm lưu trữ dữ liệu thực trong thử nghiệm này, mục tiêu của thử nghiệm này là để chứng minh sự tích hợp giữa phần mềm của tôi và lưu trữ dữ liệu thực, sử dụng một lưu trữ dữ liệu khác ở đây phá vỡ ý định này kiểm tra. Tôi cố gắng viết thử nghiệm tích hợp ít nhất có thể để chứng minh sự tích hợp này và thông thường thử nghiệm này được thực hiện bên ngoài bản dựng thông thường (ví dụ: chỉ trong các bản dựng hàng đêm)

Đôi khi tôi sử dụng HSQLDB để xây dựng các bản demo hoặc bằng chứng đơn giản - về các khái niệm, đây là một công cụ tuyệt vời, nhưng tôi không thấy vị trí của công cụ này trong quy trình phát triển bình thường của mình là gì.


0

Đối với các sản phẩm truy cập dữ liệu thử nghiệm đơn vị như MyBatis, theo tôi, các thử nghiệm sử dụng HSQLDB nhúng hoàn toàn ổn (và tôi biết ít nhất tại MyBatis họ đang sử dụng chính xác HSQLDB cho việc này).

Đối với hầu hết các dự án khác, tôi sẽ xem xét quá mức cần thiết này. Tôi sẽ thực hiện một số thử nghiệm tích hợp đơn giản (đây là các thử nghiệm có khả năng có tác dụng phụ đối với các thử nghiệm khác) truy cập cơ sở dữ liệu thực, đảm bảo rằng mỗi truy vấn / câu lệnh được sử dụng ít nhất một lần. Cần có các thử nghiệm tích hợp ít hơn nhiều so với các thử nghiệm đơn vị trong dự án.

Đối với các bài kiểm tra đơn vị, tôi sẽ chế nhạo DAO hoặc bất cứ thứ gì truy cập DB ('bộ chuyển đổi').

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.