การทดสอบการใช้งานเธรด
ในบทนี้เราจะเรียนรู้เกี่ยวกับการทดสอบการใช้งานเธรด นอกจากนี้เรายังจะได้เรียนรู้ถึงความสำคัญของการทดสอบ
ทำไมต้องทดสอบ?
ก่อนที่เราจะเจาะลึกการอภิปรายเกี่ยวกับความสำคัญของการทดสอบเราจำเป็นต้องรู้ว่าอะไรคือการทดสอบ โดยทั่วไปแล้วการทดสอบเป็นเทคนิคในการค้นหาว่าบางสิ่งทำงานได้ดีเพียงใด ในทางกลับกันโดยเฉพาะอย่างยิ่งถ้าเราพูดถึงโปรแกรมคอมพิวเตอร์หรือซอฟต์แวร์การทดสอบเป็นเทคนิคในการเข้าถึงการทำงานของโปรแกรมซอฟต์แวร์
ในส่วนนี้เราจะกล่าวถึงความสำคัญของการทดสอบซอฟต์แวร์ ในการพัฒนาซอฟต์แวร์จะต้องมีการตรวจสอบอีกครั้งก่อนที่จะปล่อยซอฟต์แวร์ไปยังไคลเอนต์ นั่นคือเหตุผลว่าทำไมการทดสอบซอฟต์แวร์โดยทีมทดสอบที่มีประสบการณ์จึงเป็นเรื่องสำคัญมาก พิจารณาประเด็นต่อไปนี้เพื่อทำความเข้าใจความสำคัญของการทดสอบซอฟต์แวร์ -
การปรับปรุงคุณภาพซอฟต์แวร์
แน่นอนว่าไม่มี บริษัท ใดต้องการส่งมอบซอฟต์แวร์คุณภาพต่ำและไม่มีลูกค้ารายใดต้องการซื้อซอฟต์แวร์คุณภาพต่ำ การทดสอบช่วยเพิ่มคุณภาพของซอฟต์แวร์โดยการค้นหาและแก้ไขข้อบกพร่องในนั้น
ความพึงพอใจของลูกค้า
ส่วนที่สำคัญที่สุดของธุรกิจคือความพึงพอใจของลูกค้า ด้วยการจัดหาซอฟต์แวร์คุณภาพดีที่ปราศจากข้อบกพร่องทำให้ บริษัท ต่างๆสามารถบรรลุความพึงพอใจของลูกค้าได้
ลดผลกระทบของคุณสมบัติใหม่
สมมติว่าเราสร้างระบบซอฟต์แวร์ 10,000 บรรทัดและเราจำเป็นต้องเพิ่มคุณสมบัติใหม่จากนั้นทีมพัฒนาจะมีความกังวลเกี่ยวกับผลกระทบของคุณสมบัติใหม่นี้กับซอฟต์แวร์ทั้งหมด นอกจากนี้การทดสอบยังมีบทบาทสำคัญเพราะหากทีมทดสอบทำการทดสอบที่ดีก็สามารถช่วยเราให้รอดพ้นจากการหยุดพักที่อาจเกิดขึ้นได้
ประสบการณ์ของผู้ใช้
อีกส่วนที่สำคัญที่สุดของธุรกิจคือประสบการณ์ของผู้ใช้ผลิตภัณฑ์นั้น ๆ เฉพาะการทดสอบเท่านั้นที่สามารถรับรองได้ว่าผู้ใช้พบว่าผลิตภัณฑ์นั้นเรียบง่ายและใช้งานง่าย
ลดค่าใช้จ่าย
การทดสอบสามารถลดต้นทุนทั้งหมดของซอฟต์แวร์ได้โดยการค้นหาและแก้ไขข้อบกพร่องในขั้นตอนการทดสอบของการพัฒนาแทนที่จะแก้ไขหลังจากส่งมอบ หากมีข้อผิดพลาดที่สำคัญหลังจากการส่งมอบซอฟต์แวร์ก็จะเพิ่มต้นทุนที่จับต้องได้พูดในแง่ของค่าใช้จ่ายและต้นทุนที่จับต้องไม่ได้พูดในแง่ของความไม่พอใจของลูกค้าชื่อเสียงด้านลบของ บริษัท เป็นต้น
จะทดสอบอะไร
ขอแนะนำให้มีความรู้ที่เหมาะสมเกี่ยวกับสิ่งที่จะทดสอบเสมอ ในส่วนนี้ก่อนอื่นเราจะเข้าใจว่าเป็นแรงจูงใจที่สำคัญของผู้ทดสอบในขณะที่ทดสอบซอฟต์แวร์ใด ๆ ความครอบคลุมของโค้ดคือจำนวนบรรทัดของโค้ดที่ชุดทดสอบของเราเข้าชมในขณะทดสอบควรหลีกเลี่ยง เป็นเพราะในขณะทดสอบการเน้นเฉพาะจำนวนบรรทัดของรหัสไม่ได้เพิ่มมูลค่าที่แท้จริงให้กับระบบของเรา อาจยังคงมีข้อบกพร่องอยู่ซึ่งจะสะท้อนให้เห็นในภายหลังในระยะต่อมาแม้ว่าจะมีการปรับใช้แล้วก็ตาม
พิจารณาประเด็นสำคัญต่อไปนี้ที่เกี่ยวข้องกับสิ่งที่ต้องทดสอบ -
เราต้องให้ความสำคัญกับการทดสอบการทำงานของโค้ดมากกว่าการครอบคลุมโค้ด
เราจำเป็นต้องทดสอบส่วนที่สำคัญที่สุดของโค้ดก่อนจากนั้นจึงย้ายไปยังส่วนที่สำคัญน้อยกว่าของโค้ด แน่นอนจะช่วยประหยัดเวลา
ผู้ทดสอบต้องมีการทดสอบที่แตกต่างกันจำนวนมากซึ่งสามารถผลักดันซอฟต์แวร์ให้ถึงขีด จำกัด
แนวทางในการทดสอบโปรแกรมซอฟต์แวร์พร้อมกัน
เนื่องจากความสามารถในการใช้ความสามารถที่แท้จริงของสถาปัตยกรรมแบบมัลติคอร์ระบบซอฟต์แวร์พร้อมกันจึงเข้ามาแทนที่ระบบตามลำดับ ในช่วงไม่กี่ครั้งที่ผ่านมามีการใช้โปรแกรมระบบพร้อมกันในทุกอย่างตั้งแต่โทรศัพท์มือถือไปจนถึงเครื่องซักผ้าตั้งแต่รถยนต์ไปจนถึงเครื่องบินเป็นต้นเราจำเป็นต้องระมัดระวังมากขึ้นเกี่ยวกับการทดสอบโปรแกรมซอฟต์แวร์พร้อมกันเพราะหากเราเพิ่มเธรดหลายเธรดลงในแอปพลิเคชันเธรดเดียวที่มี เป็นจุดบกพร่องแล้วเราจะพบกับข้อบกพร่องหลายอย่าง
เทคนิคการทดสอบสำหรับโปรแกรมซอฟต์แวร์ที่ทำงานพร้อมกันนั้นมุ่งเน้นอย่างกว้างขวางไปที่การเลือกการสอดประสานที่เปิดเผยรูปแบบที่อาจเป็นอันตรายเช่นสภาพการแข่งขันการหยุดชะงักและการละเมิดปรมาณู ต่อไปนี้เป็นสองแนวทางในการทดสอบโปรแกรมซอฟต์แวร์พร้อมกัน -
การสำรวจอย่างเป็นระบบ
แนวทางนี้มีจุดมุ่งหมายเพื่อสำรวจพื้นที่ของ interleavings ให้กว้างที่สุด แนวทางดังกล่าวสามารถใช้เทคนิคเดรัจฉานบังคับและอื่น ๆ ใช้เทคนิคการลดลำดับบางส่วนหรือเทคนิคฮิวริสติกเพื่อสำรวจช่องว่างของการแทรกสอด
ขับเคลื่อนด้วยทรัพย์สิน
แนวทางที่ขับเคลื่อนด้วยคุณสมบัติอาศัยการสังเกตว่าความผิดพลาดของการทำงานพร้อมกันมีแนวโน้มที่จะเกิดขึ้นภายใต้การแทรกสอดที่เปิดเผยคุณสมบัติเฉพาะเช่นรูปแบบการเข้าถึงหน่วยความจำที่น่าสงสัย แนวทางที่ขับเคลื่อนด้วยคุณสมบัติที่แตกต่างกันจะกำหนดเป้าหมายข้อผิดพลาดที่แตกต่างกันเช่นสภาพการแข่งขันการหยุดชะงักและการละเมิดปรมาณูซึ่งขึ้นอยู่กับคุณสมบัติเฉพาะอย่างใดอย่างหนึ่งหรืออื่น ๆ
กลยุทธ์การทดสอบ
กลยุทธ์การทดสอบเรียกอีกอย่างว่าแนวทางการทดสอบ กลยุทธ์กำหนดวิธีการทดสอบ แนวทางการทดสอบมีสองเทคนิค -
เชิงรุก
แนวทางที่เริ่มต้นกระบวนการออกแบบการทดสอบโดยเร็วที่สุดเพื่อค้นหาและแก้ไขข้อบกพร่องก่อนที่จะสร้างบิลด์
ปฏิกิริยา
วิธีการที่การทดสอบไม่เริ่มต้นจนกว่ากระบวนการพัฒนาจะเสร็จสิ้น
ก่อนที่จะใช้กลยุทธ์หรือแนวทางการทดสอบใด ๆ กับโปรแกรม python เราต้องมีแนวคิดพื้นฐานเกี่ยวกับข้อผิดพลาดที่โปรแกรมซอฟต์แวร์อาจมี ข้อผิดพลาดมีดังนี้ -
ข้อผิดพลาดทางเทคนิค
ในระหว่างการพัฒนาโปรแกรมอาจมีข้อผิดพลาดเล็ก ๆ มากมาย ข้อผิดพลาดส่วนใหญ่เกิดจากความผิดพลาดในการพิมพ์ ตัวอย่างเช่นโคลอนหายไปหรือการสะกดคีย์เวิร์ดผิดเป็นต้นข้อผิดพลาดดังกล่าวเกิดจากความผิดพลาดในไวยากรณ์ของโปรแกรมและไม่อยู่ในตรรกะ ดังนั้นข้อผิดพลาดเหล่านี้จึงเรียกว่าข้อผิดพลาดทางไวยากรณ์
ข้อผิดพลาดเชิงความหมาย
ข้อผิดพลาดทางความหมายเรียกอีกอย่างว่าข้อผิดพลาดทางตรรกะ หากมีข้อผิดพลาดทางตรรกะหรือความหมายในโปรแกรมซอฟต์แวร์คำสั่งจะคอมไพล์และรันอย่างถูกต้อง แต่จะไม่ให้ผลลัพธ์ที่ต้องการเนื่องจากตรรกะไม่ถูกต้อง
การทดสอบหน่วย
นี่เป็นหนึ่งในกลยุทธ์การทดสอบที่ใช้มากที่สุดสำหรับการทดสอบโปรแกรม python กลยุทธ์นี้ใช้สำหรับการทดสอบหน่วยหรือส่วนประกอบของโค้ด ตามหน่วยหรือส่วนประกอบเราหมายถึงคลาสหรือฟังก์ชันของรหัส การทดสอบหน่วยช่วยลดความยุ่งยากในการทดสอบระบบการเขียนโปรแกรมขนาดใหญ่โดยการทดสอบหน่วย "เล็ก" ด้วยความช่วยเหลือของแนวคิดข้างต้นการทดสอบหน่วยอาจถูกกำหนดเป็นวิธีการที่ทดสอบซอร์สโค้ดแต่ละหน่วยเพื่อตรวจสอบว่าพวกเขาส่งคืนผลลัพธ์ที่ต้องการหรือไม่
ในส่วนต่อไปเราจะเรียนรู้เกี่ยวกับโมดูล Python ต่างๆสำหรับการทดสอบหน่วย
โมดูลที่ไม่เหมาะสมที่สุด
โมดูลแรกสำหรับการทดสอบหน่วยคือโมดูลที่ไม่เหมาะสมที่สุด ได้รับแรงบันดาลใจจาก JUnit และโดยค่าเริ่มต้นรวมอยู่ใน Python3.6 สนับสนุนการทดสอบอัตโนมัติการแบ่งปันการตั้งค่าและรหัสการปิดระบบสำหรับการทดสอบการรวมการทดสอบเป็นคอลเลกชันและความเป็นอิสระของการทดสอบจากกรอบการรายงาน
ต่อไปนี้เป็นแนวคิดสำคัญบางประการที่ได้รับการสนับสนุนโดยโมดูลที่ไม่เหมาะสมที่สุด
การติดตั้งข้อความ
ใช้เพื่อตั้งค่าการทดสอบเพื่อให้สามารถรันได้ก่อนเริ่มการทดสอบและฉีกขาดหลังจากเสร็จสิ้นการทดสอบ อาจเกี่ยวข้องกับการสร้างฐานข้อมูลชั่วคราวไดเรกทอรี ฯลฯ ที่จำเป็นก่อนเริ่มการทดสอบ
กรณีทดสอบ
กรณีทดสอบจะตรวจสอบว่าการตอบกลับที่ต้องการนั้นมาจากชุดอินพุตเฉพาะหรือไม่ โมดูลที่ไม่เหมาะสมที่สุดประกอบด้วยคลาสฐานชื่อ TestCase ซึ่งสามารถใช้เพื่อสร้างกรณีทดสอบใหม่ ประกอบด้วยสองวิธีโดยค่าเริ่มต้น -
setUp()- วิธีการติดตั้งอุปกรณ์ทดสอบก่อนออกกำลังกาย สิ่งนี้ถูกเรียกก่อนที่จะเรียกใช้วิธีการทดสอบที่ใช้งาน
tearDown( - วิธีการเชื่อมต่อสำหรับการแยกโครงสร้างของชั้นเรียนหลังจากเรียกใช้การทดสอบทั้งหมดในชั้นเรียน
ชุดทดสอบ
เป็นการรวบรวมชุดทดสอบกรณีทดสอบหรือทั้งสองอย่าง
นักวิ่งทดสอบ
ควบคุมการทำงานของกรณีทดสอบหรือชุดทดสอบและให้ผลลัพธ์แก่ผู้ใช้ อาจใช้ GUI หรืออินเทอร์เฟซข้อความธรรมดาเพื่อให้ได้ผลลัพธ์
Example
โปรแกรม Python ต่อไปนี้ใช้โมดูลที่ไม่เหมาะสมที่สุดเพื่อทดสอบโมดูลที่ชื่อ Fibonacci. โปรแกรมช่วยในการคำนวณอนุกรม Fibonacci ของตัวเลข ในตัวอย่างนี้เราได้สร้างคลาสชื่อ Fibo_test เพื่อกำหนดกรณีทดสอบโดยใช้วิธีการต่างๆ วิธีการเหล่านี้สืบทอดมาจาก unittest.TestCase เราใช้สองวิธีโดยเริ่มต้น - setUp () และ tearDown () เรายังกำหนดวิธี testfibocal ชื่อของการทดสอบต้องเริ่มต้นด้วยการทดสอบตัวอักษร ในบล็อกสุดท้าย unittest.main () จัดเตรียมอินเตอร์เฟสบรรทัดคำสั่งให้กับสคริปต์ทดสอบ
import unittest
def fibonacci(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
class Fibo_Test(unittest.TestCase):
def setUp(self):
print("This is run before our tests would be executed")
def tearDown(self):
print("This is run after the completion of execution of our tests")
def testfibocal(self):
self.assertEqual(fib(0), 0)
self.assertEqual(fib(1), 1)
self.assertEqual(fib(5), 5)
self.assertEqual(fib(10), 55)
self.assertEqual(fib(20), 6765)
if __name__ == "__main__":
unittest.main()
เมื่อเรียกใช้จากบรรทัดคำสั่งสคริปต์ด้านบนจะสร้างเอาต์พุตที่มีลักษณะดังนี้ -
เอาต์พุต
This runs before our tests would be executed.
This runs after the completion of execution of our tests.
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
ตอนนี้เพื่อให้ชัดเจนขึ้นเรากำลังเปลี่ยนรหัสของเราซึ่งช่วยในการกำหนดโมดูล Fibonacci
ลองพิจารณาโค้ดบล็อกต่อไปนี้เป็นตัวอย่าง -
def fibonacci(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
มีการเปลี่ยนแปลงเล็กน้อยในบล็อกโค้ดดังที่แสดงด้านล่าง -
def fibonacci(n):
a, b = 1, 1
for i in range(n):
a, b = b, a + b
return a
ตอนนี้หลังจากรันสคริปต์ด้วยรหัสที่เปลี่ยนแปลงเราจะได้ผลลัพธ์ต่อไปนี้ -
This runs before our tests would be executed.
This runs after the completion of execution of our tests.
F
======================================================================
FAIL: testCalculation (__main__.Fibo_Test)
----------------------------------------------------------------------
Traceback (most recent call last):
File "unitg.py", line 15, in testCalculation
self.assertEqual(fib(0), 0)
AssertionError: 1 != 0
----------------------------------------------------------------------
Ran 1 test in 0.007s
FAILED (failures = 1)
เอาต์พุตด้านบนแสดงว่าโมดูลไม่สามารถให้เอาต์พุตที่ต้องการได้
โมดูล Docktest
โมดูล docktest ยังช่วยในการทดสอบหน่วย นอกจากนี้ยังมาพร้อมกับ python ใช้งานได้ง่ายกว่าโมดูลที่ไม่เหมาะสมที่สุด โมดูลที่ไม่เหมาะสมที่สุดเหมาะสำหรับการทดสอบที่ซับซ้อนมากกว่า สำหรับการใช้โมดูลหลักเราจำเป็นต้องนำเข้า docstring ของฟังก์ชันที่เกี่ยวข้องต้องมีเซสชัน python แบบโต้ตอบพร้อมกับเอาต์พุต
หากทุกอย่างเรียบร้อยดีในโค้ดของเราจะไม่มีเอาต์พุตจากโมดูล Docktest มิฉะนั้นจะให้ผลลัพธ์
ตัวอย่าง
ตัวอย่าง Python ต่อไปนี้ใช้โมดูล docktest เพื่อทดสอบโมดูลชื่อ Fibonacci ซึ่งช่วยในการคำนวณอนุกรม Fibonacci ของตัวเลข
import doctest
def fibonacci(n):
"""
Calculates the Fibonacci number
>>> fibonacci(0)
0
>>> fibonacci(1)
1
>>> fibonacci(10)
55
>>> fibonacci(20)
6765
>>>
"""
a, b = 1, 1
for i in range(n):
a, b = b, a + b
return a
if __name__ == "__main__":
doctest.testmod()
เราจะเห็นว่า docstring ของฟังก์ชันที่ชื่อ fib มีเซสชัน python แบบโต้ตอบพร้อมกับเอาต์พุต ถ้ารหัสของเราดีก็จะไม่มีผลลัพธ์จากโมดูลหลัก แต่หากต้องการดูวิธีการทำงานเราสามารถเรียกใช้ด้วยตัวเลือก –v
(base) D:\ProgramData>python dock_test.py -v
Trying:
fibonacci(0)
Expecting:
0
ok
Trying:
fibonacci(1)
Expecting:
1
ok
Trying:
fibonacci(10)
Expecting:
55
ok
Trying:
fibonacci(20)
Expecting:
6765
ok
1 items had no tests:
__main__
1 items passed all tests:
4 tests in __main__.fibonacci
4 tests in 2 items.
4 passed and 0 failed.
Test passed.
ตอนนี้เราจะเปลี่ยนรหัสที่ช่วยในการกำหนดโมดูล Fibonacci
ลองพิจารณาโค้ดบล็อกต่อไปนี้เป็นตัวอย่าง -
def fibonacci(n):
a, b = 0, 1
for i in range(n):
a, b = b, a + b
return a
บล็อกรหัสต่อไปนี้ช่วยในการเปลี่ยนแปลง -
def fibonacci(n):
a, b = 1, 1
for i in range(n):
a, b = b, a + b
return a
หลังจากรันสคริปต์แม้จะไม่มีตัวเลือก –v ด้วยรหัสที่เปลี่ยนแปลงเราจะได้ผลลัพธ์ดังที่แสดงด้านล่าง
เอาต์พุต
(base) D:\ProgramData>python dock_test.py
**********************************************************************
File "unitg.py", line 6, in __main__.fibonacci
Failed example:
fibonacci(0)
Expected:
0
Got:
1
**********************************************************************
File "unitg.py", line 10, in __main__.fibonacci
Failed example:
fibonacci(10)
Expected:
55
Got:
89
**********************************************************************
File "unitg.py", line 12, in __main__.fibonacci
Failed example:
fibonacci(20)
Expected:
6765
Got:
10946
**********************************************************************
1 items had failures:
3 of 4 in __main__.fibonacci
***Test Failed*** 3 failures.
เราจะเห็นในผลลัพธ์ข้างต้นว่าการทดสอบสามครั้งล้มเหลว