thắc mắc Các bác viết unit test thế nào ạ.

  • Người tạo chủ đề Người tạo chủ đề TrungNgaoNgo
  • Ngày bắt đầu Ngày bắt đầu
Cảm ơn bác, qua đến nay lục lại voz những cmt của bác, giống như vừa khám phá ra một chân trời mới.

Em còn một chút thắc mắc nữa, mong bác giải đáp giúp em.
Đối với adapter trong hexagonal thì thường bác sẽ test như thế nào nhỉ? (Ví dụ như message queue...v.v).
Ngoài ra nếu requirement thay đổi liên tục, thì viết test như thế nào để ít bị ảnh hưởng nhất ( ý em là production code thay đổi không làm thay đổi test)

Phần này thì ko phải Unit Test. (Thực ra mình có viết ít unit test cover cho Application Config nhưng có vẻ useless :LOL: ).

Test message queue với các infra khác, thì mình viết nguyên 1 module Integration Test với Cucumber. Nhờ QA setup test case. Rồi setup schedule job chạy hàng ngày (Mình dùng Jenkin cho nhanh).

Còn nếu bình thường test application code thôi, thì mình dùng Java Cucumber, đổi queue qua in-memory ActiveMQ rồi publish/subscribe message của queue, sau đấy verify code chạy bình thường.
 
Ngoài ra nếu requirement thay đổi liên tục, thì viết test như thế nào để ít bị ảnh hưởng nhất ( ý em là production code thay đổi không làm thay đổi test)

Quên cái này. Production code thay đổi thì test case phải failed và mình phải viết lại test. Nếu code đổi mà test ko failed thì là test viết chưa tốt. Hơi mất thời gian nhưng sau này code base sẽ ổn định, ít bị mấy lỗi ngớ ngẩn.
 
Quên cái này. Production code thay đổi thì test case phải failed và mình phải viết lại test. Nếu code đổi mà test ko failed thì là test viết chưa tốt. Hơi mất thời gian nhưng sau này code base sẽ ổn định, ít bị mấy lỗi ngớ ngẩn.
Dạ em cảm ơn bác giải đáp :) nick mới nên không Ưng được.
 
Về cơ bản thì UT cần phải chạy nhanh, dễ hiểu tới mức làm docs được luôn. Cover được behavior của prod code là ngon. Mục đích thì như các bác ở trên detect change dễ dàng. Khi nào bác sửa cái gì thì tự tin có UT chống lưng rồi, tránh break code, scope change cũng rõ ràng.
Convention thì cứ theo thánh Martin Fowler là sẽ hiệu quả. Code luôn đi kèm với UT. Legacy code = no UT
 
Mô hình thường thấy trong các project hiện tại thì có 4 tầng như này:

1. MVC, MVVM tuỳ web hay desktop apps
2. Services
3. Data Access (ORM hoặc Repositories)
4. Database (stored procedures, triggers...)

Nếu viết unit tests kỹ thì 1 feature mới phải viết test cho cả 4 tầng này.

Tầng 1 là MVC, MVVM thì có thể viết UT cho controllers, viewmodels.. cái này ko có gì bàn cãi, cứ mock thằng services rồi viết thôi.

Các tầng 2, 3, 4 thì thật sự logic nặng nhất ở tầng 3 và 4. Services đa phần chỉ là gọi thằng 3 và 4 lên thôi. Hiếm lắm mới có cái services gọi nhiều repository hoặc gọi services khác với logic if else phức tạp. Trong khi đó cái tầng 3, 4 thì câu SQL query thường phức tạp hơn rất nhiều.

Giờ có 2 hướng chọn viết UT:
Cách 1. Viết unit test cho cả 4 tầng:
  1. controllers (mock services)
  2. services (mock data access)
  3. data access (mock database)
  4. database (viết test bằng SQL scripts để verify, stored procedure tests...)
Cách 2: Viết test cho 2 chổ:
  1. controllers (mock services)
  2. services (dek mock gì cả test thẳng từ services xuống database luôn). Các thím gọi nó là unit test hay integration test cũng được, ko quan tâm.
Tôi chọn cách 2 vì trong project thực tế, deadline dí liên tục thì có sh*t mà đủ time để viết test cho cả 4 tầng như cách 1. Hơn nữa cách 1 muốn đảm bảo test đúng thì phải test đủ cả 4 tầng, đặc biệt là tầng 3, 4 nếu bỏ 2 tầng này thì coi như viết UT vô dụng.

Nói chung cân nhắc effort bỏ ra và lợi ích thu lại thôi. Mời các thím vào chém. :baffle:
Tôi công nhận với anh này , thực tế là "time công sức bỏ ra" để test 2 cái tầng kia là vô nghĩa với tôi.
Đây là chia sẽ cá nhân thôi, khi viết UT, tôi chỉ có thể mock tầng 3. data acess .is_called() = true là được .

tầng 4(sql scripts) thì toàn tự test tay thôi , tới giờ vẫn chưa biết làm sao để unittest cho chuẩn . Nhìu khi sql store nó dính tới ngày tháng để trigger , tới giờ tôi vẫn chưa biết làm sao để mock mà test luôn, toàn insert data vao test db mà test tay hoac sanity test khi dev .



Thêm 1 vi dụ tôi gặp là pyspark trên aws glue (OLAP), về cơ bản tôi chưa bik cách làm sao mock dc. Unittest chỉ test phần code trên application layer , còn các phần dính tới data(90% là sql tới aws services), gần như ko có unittest, chỉ có sanity test sau khi chạy xong các sql để validate . Nói nôm na là dev cycle : code - run code - > chạy sanity test để check expected result .
 
còn tùy dự án thế nào nữa, Unit Test ở phần thấp hơn Integration Test do nó ở mức hàm, đơn vị nhỏ, có khi viết Unit Test đúng mà Integration Test fail lòi họng đấy
 
Hiện tại ở cty tôi, tôi cho dẹp hết mấy cái UT này rồi, mấy ông bị ép viết nên viết vớ vẩn, chả có tác dụng gì cho dự án. Nên giờ tôi đưa ra 2 phương án:
1 là BDD viết bằng gherkin, cucumber...
2 là automation: cypress, playwiright, selenium...
 
Do e làm quen với Spring boot nên xin chia sẻ cách test của project như sau ạ:
Test gồm 2 phần:

+ Unit Test thuần: Sử dụng mockito và junit để mock các function call và return.
++ Ưu điểm: tăng cover code coverage và method test
++ Nhược điểm: Flow ko được kết nối dẫn đến việc function call integration có thể bị sai. Đôi lúc app deploy lên test chết sql query.

+ Integration Test: Sử dụng Spring boot test, embedded database (case của e dùng postges embedded), embedded kafka, wiremock server, aws test container để test full business flows của projects. E.g: Trigger 1 endpoint để save 1 record, request 3rd api và bắn ra 1 kafka event. Test case sẽ cực kì sát thực tế, kể cả việc db call cho ra kết quả ra sao từ các record đã được save do đó Test sẽ verify được in/out hệt như 1 QA đang làm.
++ Ưu điểm: Cover được toàn bộ case flow của project, bao gồm cả việc test sql query (do tất cả các layer đều sẽ được call đầy đủ). Tái hiện issue ở local dễ dàng bằng input từ prod hoặc dev, ko cần docker compose các downstream service ko cần thiết.
++ Nhược điểm: Tốn kha khá resource bằng việc init app mỗi test case (tuy nhiên đánh đổi từ việc up downstream service). Mock sai 3rd call hoặc kafka event dẫn đến sai test.
Kết hợp song song, app vừa dễ dàng kiểm tra được code quality vừa đảm bảo được business quality :D.
 
Sửa lần cuối:
mình làm front end, mobile, design MVVM.
Team vẫn viết unit tests bình thường, nhất là phần ViewModel.
Thấy unit tests quan trọng, viết thành thói quen tốt cho tư duy design system nữa.
 
Đúng quy trình thì viết UT trước r mới code
hay code xong mới viết UT các bác nhỉ
Chuẩn TDD là unit test trước.
Làm theo TDD thì cái quy trình Red, Green, Refactor nó lặp đi lặp lại như đi làm nhà máy luôn.

Bản chất tác dụng to nhất của Unit Test thực ra là làm thành một cái "document" sát với chính phần code nhất. Sau này cần thì cứ chạy lại cả bộ Unit Test, gần như là một cái bảo hiểm thay vì lại ngồi mò lại xem ngày xưa viết thế nào.
 
Đọc nhiều anh có vẻ ghét viết unit test, nhưng ý kiến cá nhân tôi thì lại thích viết unit test, intergation test.
Có nó thì code mới an tâm được, tha hồ refactor code. Ngoài ra việc viết unit test còn giúp những người khác hiểu/ nhìn thấy hiểu được input và output và các condition của hàm, tăng tốc độ hiểu code tránh miss nghiệp vụ.
 
ở cty cũ thì estimate là do mình, release cũng do mình

khi có issue thì dành nửa ngày để đọc, sau đó vào ngồi est, trong lúc này thì xong cái ý tưởng, và 1 happy case

tốn thời gian nhất là viết test, unit test & integration test

review code xong thì qa test. nói chung là code 3 giờ thì est 3 lần code, còn test với review code gấp 3 tiếp. trình tôi thì review cần 3 lần thời gian code, còn mấy ông level cao hơn thì có khi review 1 lần, hoặc trao đổi thêm gì đấy
 
Ae đọc hàm có thể không biết nó làm gì nhưng đọc UT với Input Output là gần như đã nắm được rồi.
Làm qua bao nhiêu cái source ko UT, mỗi lần sửa là sợ fix cái này đẻ cái khác, xong lại còn phải đọc lại code cũ người khác nữa :ah:
 

Thống kê chủ đề

Ngày tạo
TrungNgaoNgo,
Người trả lời cuối
vozphongtrao1,
Trả lời
180
Lượt xem
29.197
Quay lại
Lên đầu trang