การทดสอบการใช้งานเธรด

ในบทนี้เราจะเรียนรู้เกี่ยวกับการทดสอบการใช้งานเธรด นอกจากนี้เรายังจะได้เรียนรู้ถึงความสำคัญของการทดสอบ

ทำไมต้องทดสอบ?

ก่อนที่เราจะเจาะลึกการอภิปรายเกี่ยวกับความสำคัญของการทดสอบเราจำเป็นต้องรู้ว่าอะไรคือการทดสอบ โดยทั่วไปแล้วการทดสอบเป็นเทคนิคในการค้นหาว่าบางสิ่งทำงานได้ดีเพียงใด ในทางกลับกันโดยเฉพาะอย่างยิ่งถ้าเราพูดถึงโปรแกรมคอมพิวเตอร์หรือซอฟต์แวร์การทดสอบเป็นเทคนิคในการเข้าถึงการทำงานของโปรแกรมซอฟต์แวร์

ในส่วนนี้เราจะกล่าวถึงความสำคัญของการทดสอบซอฟต์แวร์ ในการพัฒนาซอฟต์แวร์จะต้องมีการตรวจสอบอีกครั้งก่อนที่จะปล่อยซอฟต์แวร์ไปยังไคลเอนต์ นั่นคือเหตุผลว่าทำไมการทดสอบซอฟต์แวร์โดยทีมทดสอบที่มีประสบการณ์จึงเป็นเรื่องสำคัญมาก พิจารณาประเด็นต่อไปนี้เพื่อทำความเข้าใจความสำคัญของการทดสอบซอฟต์แวร์ -

การปรับปรุงคุณภาพซอฟต์แวร์

แน่นอนว่าไม่มี บริษัท ใดต้องการส่งมอบซอฟต์แวร์คุณภาพต่ำและไม่มีลูกค้ารายใดต้องการซื้อซอฟต์แวร์คุณภาพต่ำ การทดสอบช่วยเพิ่มคุณภาพของซอฟต์แวร์โดยการค้นหาและแก้ไขข้อบกพร่องในนั้น

ความพึงพอใจของลูกค้า

ส่วนที่สำคัญที่สุดของธุรกิจคือความพึงพอใจของลูกค้า ด้วยการจัดหาซอฟต์แวร์คุณภาพดีที่ปราศจากข้อบกพร่องทำให้ บริษัท ต่างๆสามารถบรรลุความพึงพอใจของลูกค้าได้

ลดผลกระทบของคุณสมบัติใหม่

สมมติว่าเราสร้างระบบซอฟต์แวร์ 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.

เราจะเห็นในผลลัพธ์ข้างต้นว่าการทดสอบสามครั้งล้มเหลว