วิธีการทดสอบที่แตกต่างกัน
ครั้งแรกกำหนดสิ่งที่คุณกำลังทำ: หน่วยการทดสอบหรือการทดสอบการรวม จำนวนเลเยอร์นั้นไม่เกี่ยวข้องกับการทดสอบหน่วยเนื่องจากคุณจะทดสอบเพียงคลาสเดียวที่มีโอกาสมากที่สุด ที่เหลือคุณเยาะเย้ย สำหรับการทดสอบการรวมมันเป็นสิ่งที่หลีกเลี่ยงไม่ได้ที่คุณจะทดสอบหลายเลเยอร์ หากคุณมีการทดสอบหน่วยที่ดีเคล็ดลับคือการทำให้การทดสอบแบบรวมไม่ซับซ้อนเกินไป
หากการทดสอบหน่วยของคุณดีคุณไม่จำเป็นต้องทำการทดสอบซ้ำทุกรายละเอียดเมื่อทำการทดสอบการรวม
ข้อกำหนดที่เราใช้นั้นขึ้นอยู่กับแพลตฟอร์มบิต แต่คุณสามารถค้นหาได้ในเกือบทุกแพลตฟอร์มทดสอบ / พัฒนา:
ตัวอย่างการใช้งาน
ขึ้นอยู่กับเทคโนโลยีที่คุณใช้ชื่ออาจแตกต่างกัน แต่ฉันจะใช้สิ่งนี้เป็นตัวอย่าง:
หากคุณมีแอพพลิเคชั่น CRUD อย่างง่ายพร้อม Product Model, ProductsController และมุมมองดัชนีที่สร้างตาราง HTML พร้อมผลิตภัณฑ์:
ผลลัพธ์สุดท้ายของแอปพลิเคชันจะแสดงตาราง HTML พร้อมรายการผลิตภัณฑ์ทั้งหมดที่ใช้งานอยู่
การทดสอบหน่วย
แบบ
แบบจำลองที่คุณสามารถทดสอบได้ค่อนข้างง่าย มีวิธีการต่าง ๆ สำหรับมัน; เราใช้การแข่งขัน ฉันคิดว่านั่นคือสิ่งที่คุณเรียกว่า "ชุดข้อมูลปลอม" ดังนั้นก่อนการทดสอบแต่ละครั้งเราจะสร้างตารางและใส่ข้อมูลต้นฉบับ แพลตฟอร์มส่วนใหญ่มีวิธีการนี้ ตัวอย่างเช่นในคลาสทดสอบของคุณเมธอด setUp () ซึ่งรันก่อนการทดสอบแต่ละครั้ง
จากนั้นเราทำการทดสอบของเราตัวอย่างเช่น: testGetAllActive products
ดังนั้นเราจึงทดสอบโดยตรงกับฐานข้อมูลทดสอบ เราไม่ได้จำลองแหล่งข้อมูล เราทำให้มันเหมือนเดิมเสมอ สิ่งนี้ทำให้เราสามารถทดสอบกับฐานข้อมูลเวอร์ชั่นใหม่และปัญหาการสืบค้นใด ๆ ที่จะเกิดขึ้น
ในโลกแห่งความจริงคุณไม่สามารถปฏิบัติตามเสมอ 100% ความรับผิดชอบเดียว หากคุณต้องการทำสิ่งนี้ให้ดียิ่งขึ้นคุณสามารถใช้แหล่งข้อมูลที่คุณจำลอง สำหรับเรา (เราใช้ ORM) ที่ให้ความรู้สึกเหมือนทดสอบเทคโนโลยีที่มีอยู่แล้ว การทดสอบมีความซับซ้อนมากขึ้นและการทดสอบก็ไม่ได้ทดสอบจริง ๆ ดังนั้นเราจึงทำเช่นนี้
ข้อมูลที่เข้ารหัสแบบฮาร์ดจะถูกจัดเก็บแยกต่างหากในส่วนควบ ดังนั้นฟิกซ์เจอร์ก็เหมือนไฟล์ SQL ที่มีคำสั่งสร้างตารางและแทรกสำหรับบันทึกที่เราใช้ เราทำให้พวกเขามีขนาดเล็กเว้นแต่จะมีความต้องการที่แท้จริงในการทดสอบกับบันทึกจำนวนมาก
class ProductModel {
public function getAllActive() {
return $this->find('all', array('conditions' => array('active' => 1)));
}
}
ตัวควบคุม
คอนโทรลเลอร์ต้องการงานมากกว่านี้เพราะเราไม่ต้องการทดสอบโมเดลด้วย ดังนั้นสิ่งที่เราทำคือเลียนแบบโมเดล นั่นหมายถึง: เราทดสอบ: index () วิธีการที่ควรกลับรายการของบันทึก
ดังนั้นเราจึงจำลองวิธีการแบบ getAllActive () ออกและเพิ่มข้อมูลคงที่ในนั้น (ตัวอย่างเช่นสองรายการ) ตอนนี้เราทดสอบข้อมูลที่ผู้ควบคุมส่งไปยังมุมมองและเราเปรียบเทียบว่าเราได้รับทั้งสองระเบียนกลับมาหรือไม่
function testProductIndexLoggedIn() {
$this->setLoggedIn();
$this->ProductsController->mock('ProductModel', 'index', function(return array(your records) ));
$result=$this->ProductsController->index();
$this->assertEquals(2, count($result['products']));
}
พอแล้ว. เราพยายามเพิ่มฟังก์ชั่นเล็ก ๆ น้อย ๆ ให้กับคอนโทรลเลอร์เพราะนั่นทำให้การทดสอบนั้นยาก แต่แน่นอนว่าจะมีรหัสอยู่ด้วยเสมอ ตัวอย่างเช่นเราทดสอบข้อกำหนดเช่น: แสดงสองระเบียนเหล่านั้นเฉพาะเมื่อคุณลงชื่อเข้าใช้
ดังนั้นตัวควบคุมต้องการการเยาะเย้ยหนึ่งครั้งตามปกติและข้อมูล hardcoded ขนาดเล็ก สำหรับระบบเข้าสู่ระบบอาจเป็นอีกระบบหนึ่ง ในการทดสอบของเราเรามีวิธีการช่วยเหลือสำหรับมัน: setLoggedIn () ทำให้ง่ายต่อการทดสอบด้วยการเข้าสู่ระบบหรือไม่มีการเข้าสู่ระบบ
class ProductsController {
public function index() {
if($this->loggedIn()) {
$this->set('products', $this->ProductModel->getAllActive());
}
}
}
เข้าชม
การทดสอบการดูเป็นเรื่องยาก ก่อนอื่นเราแยกตรรกะออกซึ่งทำซ้ำ เราวางไว้ในผู้ช่วยเหลือและทดสอบคลาสเหล่านั้นอย่างเข้มงวด เราคาดหวังผลลัพธ์เดียวกันเสมอ ตัวอย่างเช่น generateHtmlTableFromArray ()
จากนั้นเรามีมุมมองเฉพาะของโครงการ เราไม่ทดสอบสิ่งเหล่านั้น ไม่ต้องการทดสอบหน่วยเหล่านั้นจริงๆ เราเก็บไว้สำหรับการทดสอบการรวม เนื่องจากเรานำรหัสจำนวนมากออกไปสู่มุมมองเราจึงมีความเสี่ยงต่ำกว่าที่นี่
หากคุณเริ่มทดสอบสิ่งที่คุณอาจต้องเปลี่ยนการทดสอบทุกครั้งที่คุณเปลี่ยนชิ้นส่วนของ HTML ซึ่งไม่เป็นประโยชน์สำหรับโครงการส่วนใหญ่
echo $this->tableHelper->generateHtmlTableFromArray($products);
การทดสอบบูรณาการ
ขึ้นอยู่กับแพลตฟอร์มของคุณที่นี่คุณสามารถทำงานร่วมกับเรื่องราวของผู้ใช้ ฯลฯ มันอาจจะเป็น webbased เช่นSeleniumหรือโซลูชันอื่น ๆ ที่เทียบเท่ากัน
โดยทั่วไปเราเพิ่งโหลดฐานข้อมูลพร้อมติดตั้งและยืนยันว่าข้อมูลใดควรพร้อมใช้งาน สำหรับการทดสอบแบบบูรณาการโดยทั่วไปเราใช้ข้อกำหนดระดับโลกมาก ดังนั้น: ตั้งค่าผลิตภัณฑ์ให้เปิดใช้งานและตรวจสอบว่าผลิตภัณฑ์นั้นพร้อมใช้งานหรือไม่
เราไม่ได้ทดสอบทุกอย่างอีกเช่นว่ามีฟิลด์ที่เหมาะสมหรือไม่ เราทดสอบข้อกำหนดที่ใหญ่กว่าที่นี่ เนื่องจากเราไม่ต้องการทำซ้ำการทดสอบของเราจากคอนโทรลเลอร์หรือมุมมอง หากมีบางอย่างที่เป็นกุญแจ / ส่วนหลักของแอปพลิเคชันของคุณหรือเพื่อเหตุผลด้านความปลอดภัย (ตรวจสอบรหัสผ่านไม่พร้อมใช้งาน) เราจะเพิ่มสิ่งเหล่านั้นเพื่อให้แน่ใจว่าถูกต้อง
ข้อมูลที่เข้ารหัสยากถูกเก็บไว้ในส่วนควบ
function testIntegrationProductIndexLoggedIn() {
$this->setLoggedIn();
$result=$this->request('products/index');
$expected='<table';
$this->assertContains($expected, $result);
// Some content from the fixture record
$expected='<td>Product 1 name</td>';
$this->assertContains($expected, $result);
}