iT邦幫忙

2024 iThome 鐵人賽

DAY 18
0
Software Development

LSTM結合Yolo v8對於多隻斑馬魚行為分析系列 第 18

day 18寫一個mock test斑馬魚的介面測試

  • 分享至 

  • xImage
  •  

今天是第十八天我們可以寫一個mock test來測試我們寫的斑馬魚軟體介面,以下是程式碼

import unittest
from unittest.mock import patch, MagicMock
import tkinter as tk
from tkinter import ttk
from your_module import perform_yolo, show_zebrafish_window, select_file, select_weight_file  # 假設這些函數在 your_module 中定義

class TestZebrafishGUI(unittest.TestCase):
    def setUp(self):
        # 初始化tkinter主窗口
        self.root = tk.Tk()
        self.root.withdraw()  # 隱藏主窗口
        
        # 初始化檔案路徑變數
        self.file_path_var = tk.StringVar()
        self.weight_value_var = tk.StringVar()
        
        # 初始化主框架和小部件
        self.main_frame = ttk.Frame(self.root)
        self.main_frame.grid(row=0, column=0, sticky="nsew")

        # 建立 image_label 來顯示圖片
        self.image_label = ttk.Label(self.main_frame)
        self.image_label.grid(row=4, column=0, columnspan=3, padx=5, pady=5, sticky="nsew")

    def test_select_file(self):
        with patch('your_module.filedialog.askopenfilename', return_value='/path/to/image.gif'):
            select_file()
            self.assertEqual(self.file_path_var.get(), '/path/to/image.gif')

    def test_select_weight_file(self):
        with patch('your_module.filedialog.askopenfilename', return_value='/path/to/weights.weights'):
            select_weight_file()
            self.assertEqual(self.weight_value_var.get(), '/path/to/weights.weights')

    def test_perform_yolo(self):
        # 模擬 YOLO 計算
        with patch('your_module.yolo_calculate', return_value='/path/to/result.gif'), \
             patch('your_module.load_image'), \
             patch('your_module.show_zebrafish_window') as mock_show_window:
            perform_yolo()
            mock_show_window.assert_called_once()

    def test_show_zebrafish_window(self):
        with patch('your_module.ttk.Button') as mock_button:
            show_zebrafish_window()
            self.assertTrue(mock_button.called)

    def tearDown(self):
        self.root.destroy()

if __name__ == '__main__':
    unittest.main()

引入必要的模組

import unittest
from unittest.mock import patch, MagicMock
import tkinter as tk
from tkinter import ttk
from your_module import perform_yolo, show_zebrafish_window, select_file, select_weight_file
  • unittest:Python 的內建測試框架,用來編寫和執行測試案例。
  • unittest.mock:這是一個允許你在測試中替代和模擬 Python 物件的模組。它提供了 patchMagicMock 來模擬和替換真實的函數或物件。
  • tkinterttk:Python 的標準 GUI 庫,用來建立視覺化介面。
  • from your_module import ...:假設你的 perform_yolo, show_zebrafish_window, select_file, select_weight_file 函數在 your_module 中定義,這一行將它們匯入以供測試。

初始化測試環境

class TestZebrafishGUI(unittest.TestCase):
    def setUp(self):
        # 初始化tkinter主窗口
        self.root = tk.Tk()
        self.root.withdraw()  # 隱藏主窗口
        
        # 初始化檔案路徑變數
        self.file_path_var = tk.StringVar()
        self.weight_value_var = tk.StringVar()
        
        # 初始化主框架和小部件
        self.main_frame = ttk.Frame(self.root)
        self.main_frame.grid(row=0, column=0, sticky="nsew")

        # 建立 image_label 來顯示圖片
        self.image_label = ttk.Label(self.main_frame)
        self.image_label.grid(row=4, column=0, columnspan=3, padx=5, pady=5, sticky="nsew")
  • setUp(self)unittest 框架中的 setUp() 方法在每次執行測試之前自動運行。它主要用來設定測試的初始條件。
  • self.root = tk.Tk():建立 tkinter 的主窗口。
  • self.root.withdraw():隱藏主窗口。這在測試中很常見,因為通常不需要真正顯示 GUI。
  • self.file_path_varself.weight_value_var:這些是 tkinter 的字串變數,用來儲存選擇的檔案路徑和權重檔案路徑。
  • self.main_frame:建立一個框架來容納介面中的小部件。
  • self.image_label:建立一個用來顯示圖像的標籤。

測試選擇檔案的功能

    def test_select_file(self):
        with patch('your_module.filedialog.askopenfilename', return_value='/path/to/image.gif'):
            select_file()
            self.assertEqual(self.file_path_var.get(), '/path/to/image.gif')
  • patch('your_module.filedialog.askopenfilename', return_value='/path/to/image.gif'):使用 patch 來模擬 filedialog.askopenfilename 的行為,並設定它返回一個固定的檔案路徑。
  • select_file():呼叫模擬過的 select_file() 函數。
  • self.assertEqual(self.file_path_var.get(), '/path/to/image.gif'):驗證 file_path_var 變數的值是否與預期的檔案路徑相同。

測試選擇權重檔案的功能

    def test_select_weight_file(self):
        with patch('your_module.filedialog.askopenfilename', return_value='/path/to/weights.weights'):
            select_weight_file()
            self.assertEqual(self.weight_value_var.get(), '/path/to/weights.weights')

這段程式碼與 test_select_file() 類似,只是它測試的是選擇權重檔案的功能。

測試執行 YOLO 計算的功能

    def test_perform_yolo(self):
        # 模擬 YOLO 計算
        with patch('your_module.yolo_calculate', return_value='/path/to/result.gif'), \
             patch('your_module.load_image'), \
             patch('your_module.show_zebrafish_window') as mock_show_window:
            perform_yolo()
            mock_show_window.assert_called_once()
  • patch('your_module.yolo_calculate', return_value='/path/to/result.gif'):模擬 yolo_calculate 函數,設定它返回一個固定的結果圖像路徑。
  • patch('your_module.load_image'):模擬 load_image 函數,因為我們在測試中不需要真的去加載圖像。
  • patch('your_module.show_zebrafish_window') as mock_show_window:模擬 show_zebrafish_window 函數,並將其模擬物件命名為 mock_show_window
  • perform_yolo():呼叫 perform_yolo 函數。
  • mock_show_window.assert_called_once():檢查 show_zebrafish_window 是否被正確呼叫一次。

測試顯示斑馬魚分析視窗的功能

    def test_show_zebrafish_window(self):
        with patch('your_module.ttk.Button') as mock_button:
            show_zebrafish_window()
            self.assertTrue(mock_button.called)
  • patch('your_module.ttk.Button') as mock_button:模擬 ttk.Button,以便監控按鈕的建立。
  • show_zebrafish_window():呼叫 show_zebrafish_window 函數。
  • self.assertTrue(mock_button.called):驗證 ttk.Button 是否有被呼叫,確認按鈕有被正確建立。

測試結束後的清理工作

    def tearDown(self):
        self.root.destroy()
  • tearDown(self)unittest 框架中的 tearDown() 方法在每次測試之後自動運行。它主要用來清理測試環境。
  • self.root.destroy():銷毀 tkinter 主窗口,釋放資源。

執行測試

if __name__ == '__main__':
    unittest.main()
  • 這一行確保當腳本直接執行時,unittest 會自動搜尋並運行所有定義在這個檔案中的測試。

總結

這個測試代碼模擬了 tkinter GUI 的行為,並確保各個功能在測試中能夠正確運作。透過 unittestunittest.mock 的結合,我可以有效地檢查 GUI 程式碼的功能是否符合預期。


上一篇
Day 17yolo辨識腳踏車速率
下一篇
day 19 Yolo分析公路車胎壓結合lstm換輪胎時間
系列文
LSTM結合Yolo v8對於多隻斑馬魚行為分析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言