Chào các bạn và mình lại trở lại với chủ để học cơm Và từ đây sẽ là những chuỗi bài dịch về làm thế nào để tự học, tự code. Và tôi, một người rất gắn bó với công việc training, nghĩa là giúp đỡ các bạn mới vào nghề lập trình có thể bước đi tự tin trên con đường này hơn Mở đầu cho một seri nhàm chán nhưng có lẽ lại rất quan trọng với các bạn newbie này, tôi xin chọn tác giả Bill Gathen, một lập trình viên ruby kỳ cựu. Các bài của ông ấy không chỉ focus vào riêng ngôn ngữ ruby mà nó còn là sự so sánh tương quan giữa các ngôn ngữ lập trình khác nữa. Trong các bài dịch mình sẽ cố gắng đưa những ví dụ cụ thể dễ hiểu hơn vào, hoặc những đoạn dịch theo văn phong người Việt cho dễ hiểu. Nhưng cá nhân mình vẫn muốn các bạn đọc bài viết gốc hơn vì nó đảm bảo tính xác thực, đồng thời cũng là 1 lần rèn vốn tiếng Anh của chính bạn ## Phần 1: Lập trình viên có cần test code như QA không? #### I. Mở đầu Bài viết gốc: khuyến cáo nên đọc trước [Bill Gathen - http://www.codenewbie.org/blogs/testing-your-code](http://www.codenewbie.org/blogs/testing-your-code) Có thể bạn đã nghe người ta thảo luận với nhau rất nhiều về việc tự test code. Hay nói một cách khác đó là thể hiện quy trình yêu cầu của ứng dụng bằng những đoạn code. Nhưng tất cả chỉ có vậy thôi sao? Để hiểu được lý do tạo sao chúng ta cần kiểm tra code có hoạt động đúng hay không thì hãy bắt đầu với một ví dụ đơn giản ```java def multiply_by_two (n) n * 2 ``` Bạn thấy có gì sai ở đoạn code trên không? #### II. Test code và tầm quan trọng của nó Đây là đoạn code được viết bằng ngôn ngữ Ruby, thậm chí nếu bạn không hiểu Ruby là gì thì bạn có thể đoán đoạn code trên xử lý vấn đề gì qua tên của nó, vì vậy tôi có thể nói đoạn code trên là đúng. Nếu bạn hỏi tại sao không thấy việc return giá trị như Javascript, đó là bởi vì đặc thù của Ruby hắn sẽ tự động trả về biểu thức cuối cùng xử lý, do đó chúng ta không cần phải khai báo return. (Dịch giả: Hoặc có 1 tranh luận khá thú vị khi tôi mới join 1 cty, có 1 bạn tên HoangCongMinh sau khi review code Java của tôi thì bạn đã comment đoạn code return a==true?method_b():method_c(); thực ra việc return method trong trường hợp này chỉ đúng vs Ruby thôi còn java thì chịu, hoặc là trình độ của tôi chưa thấm đến đoạn này.) Nhìn thì nó có vẻ ngon đấy, nhưng làm sao chúng ta có thể chắn chắn rằng nó sẽ hoạt động một cách chính xác? Và chúng ta cần phải chạy đoạn code ở trên để kiểm tra xem kết quả trả về có đúng như mong đợi hay không? Ruby có một công cụ hỗ trợ biên dịch đoạn code trực tiếp là IRB xem chúng chạy như thế là. IRB là gì thì bạn có thể tham khảo thêm trên google để hiểu rõ nhé (Dịch giả) Chúng ta khởi động ứng dụng IRB bằng command 'irb', chúng ta cung cấp cho nó 1 đoạn ví dụ để chạy. với IRB thì chúng ta có thể thử 1 method với những giá trị đối số khác nhau. Giả dụ đoạn mã test thử của chúng ta làm trong 1 file tên math.rb, đoạn mã test IRB sẽ như thế này? ```java > IRB 2.2.0: 001> require './math' => Đúng 2.2.0: 002> multiply_by_two 2 => 4 2.2.0: 003> multiply_by_two -2 => -4 ``` "require" để yêu cùng file để chúng ta làm việc với nó, sau đó chúng ta gọi đến method trong file đó mà chúng ta muốn test với bất kỳ đối số nào mà chúng ta thích. Giá trị trả về sẽ xuất hiện trên các dòng tiếp theo với ký tự (=>). Chúng ta test với 2 đối số của method multiply_by_two là 2 và -2, và thấy giá trị trả về OK -> vậy đoạn code này OK? Tuy nhiên 2, -2 là các đối số lý tưởng nhưng với các trường hợp khác thì sao? Điều gì sẽ xảy ra nếu chung ta quên không cung cấp đối số cho method? hoặc chúng ta truyền vào đối số không phải là 1 số mà là 1 biến chưa gán giá trị thì sao? Hãy thử và xem nhé ```java 2.2.0: 004> multiply_by_two ArgumentError: sai số của đối số (0 trong 1) from /Users/bill/dev/math.rb:1:in 'multiply_by_two' from (IRB): 4 từ /Users/bill/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `main' 2.2.0: 005> multiply_by_two "ruby" => "Rubyruby" 2.2.0: 006> multiply_by_two nil NoMethodError: Phương pháp xác định `* 'cho con số không: NilClass from /Users/bill/dev/math.rb:2:in 'multiply_by_two' from (IRB): 6 from /Users/bill/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `main' ``` Có vẻ như chúng ta đã gặp vấn đề ở đây, dù không phải tất cả các trường hợp. Và chúng ta cần handle những error có thể không đúng với kịch bản ở trên. Với cách đó thì đoạn code sẽ không bị lỗi nữa. ```java def multiply_by_two (n = "không có giá trị cung cấp")  if (n.is_a? (Integer))  n * 2  khác  nâng ArgumentError.new ( "Xin vui lòng cung cấp một số hợp lệ") ```  Với những giá trị không hợp lệ chúng ta sẽ đưa ra thông báo tương ứng cho người dùng. Và bạn hãy kiểm tra lại 1 lần nữa để đảm bảo rằng đoạn code đã chạy đúng. ```java > IRB 2.2.0: 001> require './math' => Đúng 2.2.0: 002> multiply_by_two 2 => 4 2.2.0: 003> multiply_by_two -2 => -4 2.2.0: 004> multiply_by_two ArgumentError: Xin cung cấp một số hợp lệ  from /Users/bill/dev/math.rb:3:in 'multiply_by_two'  from (IRB): 4  from /Users/bill/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `<main>' 2.2.0: 005> multiply_by_two "ruby" ArgumentError: Xin cung cấp một số hợp lệ  from /Users/bill/dev/math.rb:3:in 'multiply_by_two'  from (IRB): 5  from /Users/bill/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `<main> ' 2.2.0: 006> multiply_by_two nil ArgumentError: Xin cung cấp một số hợp lệ  from /Users/bill/dev/math.rb:3:in 'multiply_by_two'  from (IRB): 6  from /Users/bill/.rvm/rubies/ruby-2.2.0/bin/irb:11:in `<main> ' ``` Với việc test liên tục từ những gía trị hợp lý đến những giá trị bất hợp lý chúng ta cũng không phá vỡ logic của method, hãy nâng cao việc handle các lỗi có thể xảy ra với những message hữu ích với người dùng. #### III. Kết luận Nếu chúng ta có thể kiểm soát được tất cả các tình huống gây ra lỗi thì ứng dụng của chúng ta sẽ được người dùng yêu thích hơn, và sản phẩm của chúng ta có giá trị hơn. Với mỗi đoạn code xử lý hết lỗi vừa hạn chế thời gian test của QA vừa hạn chế được những lỗi gây gián đoạn chương trình đồng thời còn làm giảm chi phí phát triển và giảm thời gian maintain sau này Với những lợi ích to lớn của việc test code ở trên thì chắc hẳn bạn đã tự trả lời được câu hỏi test code có quan trọng với anh em lập trình viên chúng ta hay không rồi chứ