ผลต่างระหว่างรุ่นของ "Afgu/unit testing 1"

จาก Theory Wiki
ไปยังการนำทาง ไปยังการค้นหา
แถว 42: แถว 42:
  
 
* true ถ้าวงกลมทั้งสองวงมีเส้นรอบวงที่ตัดกันหรือสัมผัสกัน (ถ้าวงกลมที่ซ้อนกันไม่นับ)
 
* true ถ้าวงกลมทั้งสองวงมีเส้นรอบวงที่ตัดกันหรือสัมผัสกัน (ถ้าวงกลมที่ซ้อนกันไม่นับ)
 
=== กรณีต่าง ๆ ===
 
  
 
สมมติว่ามีคนเขียนฟังก์ชันดังกล่าวมาให้เรา เราจะ "ทดสอบ" อะไรบ้าง ที่ทำให้เราเชื่อได้ว่าฟังก์ชันดังกล่าวทำงานได้ถูกต้อง?
 
สมมติว่ามีคนเขียนฟังก์ชันดังกล่าวมาให้เรา เราจะ "ทดสอบ" อะไรบ้าง ที่ทำให้เราเชื่อได้ว่าฟังก์ชันดังกล่าวทำงานได้ถูกต้อง?
  
==== กรณีทดสอบตัวอย่าง ====
+
=== กรณีทดสอบตัวอย่าง ===
  
 
ตัวอย่างหนึ่งที่เราทดสอบได้คือกรณีที่วงกลมสองวงห่างกันมาก ๆ จนเส้นรอบวงไม่ทับกัน  (เราควรวาดรูปประกอบด้วย)
 
ตัวอย่างหนึ่งที่เราทดสอบได้คือกรณีที่วงกลมสองวงห่างกันมาก ๆ จนเส้นรอบวงไม่ทับกัน  (เราควรวาดรูปประกอบด้วย)
แถว 66: แถว 64:
 
   });
 
   });
  
 +
});
 +
</pre>
 +
 +
=== เขียนโค้ด ===
 +
 +
สังเกตว่าเรายังไม่ได้เขียนโค้ดอะไรเลยของฟังก์ชัน <tt>cirIntersect</tt> เราลองใช้ browser เปิด <tt>index-test.html</tt>  เราจะเห็นว่าโปรแกรมของเรายังไม่ผ่านการทดสอบดังกล่าว
 +
 +
จากกรณีทดสอบตัวอย่าง เราจะแก้โค้ดของฟังก์ชันเพื่อให้ทำงานให้ผ่าน  (ถ้าเราต้องการทำตามหลักการ เราจะเขียนโค้ดให้ง่ายที่สุดให้โปรแกรมทำงานผ่านข้อมูลทดสอบนี้)
 +
 +
เราอาจจะเขียนฟังก์ชันดังกล่าวดังนี้
 +
 +
function cirIntersect(x1, y1, r1, x2, y2, r2) {
 +
  return false;
 +
}
 +
 +
แต่เรามองแว่บเดียวก็เห็นแล้วว่าฟังก์ชันดังกล่าวทำงานไม่ถูกแน่ ๆ แต่ถ้ากรณีทดสอบเรามีแค่ข้อเดียวดังข้างต้น เราก็ไม่สามารถบอกได้ว่าโค้ดขำ ๆ ข้างบนนี้ทำงานผิดพลาด
 +
 +
=== เพิ่มกรณีทดสอบ ===
 +
 +
ลองเขียนกรณีทดสอบเพิ่ม โดยระบุในส่วน <tt>it('.....',function(){});</tt>  ดังตัวอย่าง:
 +
 +
<pre>
 +
describe('cirIntersect', function(){
 +
  // ...
 
   it('should blah blah', function(){
 
   it('should blah blah', function(){
 
     // ...
 
     // ...
 
   });
 
   });
 
 
});
 
});
 
</pre>
 
</pre>

รุ่นแก้ไขเมื่อ 12:53, 10 พฤศจิกายน 2556

เราใช้หัดเขียน unit test บน java script ซึ่งเป็นภาษาที่ทุกคนน่าจะสามารถเรียกให้ทำงานได้ ในครั้งแรกเราจะเน้นให้เข้าใจว่า unit test คืออะไร และสามารถเขียน unit test แบบทั่วไปได้ ในครั้งถัด ๆ ไปเราจะศึกษาเทคนิคเพิ่มเติมเช่นการทำ isolation รวมไปถึงการเขียน unit test ที่ดี

เราสามารถทำ unit testing ได้โดยไม่ต้องใช้ framework ใด ๆ เลยก็ได้ แต่ในที่นี้เราจะใช้ mocha เป็น framework mocha รองรับไลบรารีการ assert/expect ได้หลายแบบ เราเลือกใช้ chai นอกจากนี้ mocha ยังต้องการใช้ jquery ในการแสดงผล เราจึงต้องเรียก jquery ด้วย

ไลบรารีที่ใช้:

ที่เราเลือกใช้ mocha และ Chai นั้นเป็นตามรสนิยมผู้สอน ในการใช้งานจริง แนะนำให้เลือกไลบรารี/เฟรมเวิร์คที่ชอบตามสะดวก

โครงสร้างไดเร็กทอรี

ในแต่ละตัวอย่างและแบบฝึกหัดที่เราจะเขียน เราจะใช้โครงสร้างไดเร็กทอรีดังนี้

- project/
  - *.js  (ไฟล์ js ของ project)
  - test/
    - index-test.html
    - test.js    (เก็บโค้ดสำหรับ test)
    - lib/
      - mocha.js
      - mocha.css
      - chai.js
      - jquery.js

สามารถดาวน์โหลด template ดังกล่าวได้: project.tgz, project.zip และเปลี่ยนชื่อไดเร็กทอรีตามความเหมาะสม

ตัวอย่าง

เราต้องการเขียนฟังก์ชัน

function cirIntersect(x1, y1, r1, x2, y2, r2) {
}

ที่รับข้อมูล

  • วงกลมวงแรก ที่มีจุดศูนย์กลางที่ตำแหน่ง (x1,y1) รัศมี r1 และ
  • วงกลมวงที่สอง ที่มีจุดศูนย์กลางที่ตำแหน่ง (x2,y2) รัศมี r2

จากนั้นคืนค่า

  • true ถ้าวงกลมทั้งสองวงมีเส้นรอบวงที่ตัดกันหรือสัมผัสกัน (ถ้าวงกลมที่ซ้อนกันไม่นับ)

สมมติว่ามีคนเขียนฟังก์ชันดังกล่าวมาให้เรา เราจะ "ทดสอบ" อะไรบ้าง ที่ทำให้เราเชื่อได้ว่าฟังก์ชันดังกล่าวทำงานได้ถูกต้อง?

กรณีทดสอบตัวอย่าง

ตัวอย่างหนึ่งที่เราทดสอบได้คือกรณีที่วงกลมสองวงห่างกันมาก ๆ จนเส้นรอบวงไม่ทับกัน (เราควรวาดรูปประกอบด้วย)

กรณี กรณีที่ทดสอบ x1 y1 r1 x2 y2 r2 return
1 วงกลมห่างกัน 0 0 10 100 0 10 false

ใน test.js เราจะอธิบายกรณีทดสอบนี้ได้ดังนี้

describe('cirIntersect', function(){

  it('should return false when two circles are far apart', function(){
    assert(cirIntersect(0,0,10,100,0,10)==false);
  });

});

เขียนโค้ด

สังเกตว่าเรายังไม่ได้เขียนโค้ดอะไรเลยของฟังก์ชัน cirIntersect เราลองใช้ browser เปิด index-test.html เราจะเห็นว่าโปรแกรมของเรายังไม่ผ่านการทดสอบดังกล่าว

จากกรณีทดสอบตัวอย่าง เราจะแก้โค้ดของฟังก์ชันเพื่อให้ทำงานให้ผ่าน (ถ้าเราต้องการทำตามหลักการ เราจะเขียนโค้ดให้ง่ายที่สุดให้โปรแกรมทำงานผ่านข้อมูลทดสอบนี้)

เราอาจจะเขียนฟังก์ชันดังกล่าวดังนี้

function cirIntersect(x1, y1, r1, x2, y2, r2) {
  return false;
}

แต่เรามองแว่บเดียวก็เห็นแล้วว่าฟังก์ชันดังกล่าวทำงานไม่ถูกแน่ ๆ แต่ถ้ากรณีทดสอบเรามีแค่ข้อเดียวดังข้างต้น เราก็ไม่สามารถบอกได้ว่าโค้ดขำ ๆ ข้างบนนี้ทำงานผิดพลาด

เพิ่มกรณีทดสอบ

ลองเขียนกรณีทดสอบเพิ่ม โดยระบุในส่วน it('.....',function(){}); ดังตัวอย่าง:

describe('cirIntersect', function(){
  // ...
  it('should blah blah', function(){
    // ...
  });
});

สิ่งที่ต้องใส่ใจ

แบบฝึกหัด