成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

用C語言對Gtk+應用進行功能測試

開發 后端
自動化測試用來保證你程序的質量以及讓它以預想的運行。單元測試只是檢測你算法的某一部分,而并不注重各組件間的適應性。這就是為什么會有功能測試,它有時也稱為集成測試。

[[206159]]

這個簡單教程教你如何測試你應用的功能。

自動化測試用來保證你程序的質量以及讓它以預想的運行。單元測試只是檢測你算法的某一部分,而并不注重各組件間的適應性。這就是為什么會有功能測試,它有時也稱為集成測試。

功能測試簡單地與你的用戶界面進行交互,無論它是網站還是桌面應用。為了展示功能測試如何工作,我們以測試一個 Gtk+ 應用為例。為了簡單起見,這個教程里,我們使用 Gtk+ 2.0 教程的示例。

基礎設置

對于每一個功能測試,你通常需要定義一些全局變量,比如 “用戶交互時延” 或者 “失敗的超時時間”(也就是說,如果在指定的時間內一個事件沒有發生,程序就要中斷)。

  1. #define TTT_FUNCTIONAL_TEST_UTIL_IDLE_CONDITION(f) ((TttFunctionalTestUtilIdleCondition)(f)) 
  2. #define TTT_FUNCTIONAL_TEST_UTIL_REACTION_TIME (125000) 
  3. #define TTT_FUNCTIONAL_TEST_UTIL_REACTION_TIME_LONG (500000) 
  4. typedef gboolean (*TttFunctionalTestUtilIdleCondition)(gpointer data); 
  5. struct timespec ttt_functional_test_util_default_timeout = { 
  6.   20, 
  7.   0, 
  8. }; 

現在我們可以實現我們自己的超時函數。這里,為了能夠得到期望的延遲,我們采用 usleep 函數。

  1. void 
  2. ttt_functional_test_util_reaction_time() 
  3.   usleep(TTT_FUNCTIONAL_TEST_UTIL_REACTION_TIME); 
  4. void 
  5. ttt_functional_test_util_reaction_time_long() 
  6.   usleep(TTT_FUNCTIONAL_TEST_UTIL_REACTION_TIME_LONG); 

直到獲得控制狀態,超時函數才會推遲執行。這對于一個異步執行的動作很有幫助,這也是為什么采用這么長的時延。

  1. void 
  2. ttt_functional_test_util_idle_condition_and_timeout( 
  3.      TttFunctionalTestUtilIdleCondition idle_condition, 
  4.      struct timespec *timeout, 
  5.      pointer data) 
  6.   struct timespec start_time, current_time
  7.   clock_gettime(CLOCK_MONOTONIC, 
  8.                 &start_time); 
  9.   while(TTT_FUNCTIONAL_TEST_UTIL_IDLE_CONDITION(idle_condition)(data)){ 
  10.     ttt_functional_test_util_reaction_time(); 
  11.     clock_gettime(CLOCK_MONOTONIC, 
  12.                   &current_time); 
  13.     if(start_time.tv_sec + timeout->tv_sec < current_time.tv_sec){ 
  14.       break; 
  15.     } 
  16.   } 
  17.   ttt_functional_test_util_reaction_time(); 

與圖形化用戶界面交互

為了模擬用戶交互的操作, Gdk 庫 為我們提供了一些需要的函數。要完成我們的工作,我們只需要如下 3 個函數:

  • gdk_display_warp_pointer()
  • gdk_test_simulate_button()
  • gdk_test_simulate_key()

舉個例子,為了測試按鈕點擊,我們可以這么做:

  1. gboolean 
  2. ttt_functional_test_util_button_click(GtkButton *button) 
  3.   GtkWidget *widget; 
  4.   GdkWindow *window; 
  5.   gint x, y; 
  6.   gint origin_x, origin_y; 
  7.   if(button == NULL || 
  8.      !GTK_IS_BUTTON(button)){ 
  9.     return(FALSE); 
  10.   } 
  11.   widget = button; 
  12.   if(!GTK_WIDGET_REALIZED(widget)){ 
  13.     ttt_functional_test_util_reaction_time_long(); 
  14.   } 
  15.   /* retrieve window and pointer position */ 
  16.   gdk_threads_enter(); 
  17.   window = gtk_widget_get_window(widget); 
  18.   x = widget->allocation.x + widget->allocation.width / 2.0; 
  19.   y = widget->allocation.y + widget->allocation.height / 2.0; 
  20.   gdk_window_get_origin(window, &origin_x, &origin_y); 
  21.   gdk_display_warp_pointer(gtk_widget_get_display(widget), 
  22.                            gtk_widget_get_screen(widget), 
  23.                            origin_x + x, origin_y + y); 
  24.   gdk_threads_leave(); 
  25.   /* click the button */ 
  26.   ttt_functional_test_util_reaction_time(); 
  27.   gdk_test_simulate_button(window, 
  28.                            x, 
  29.                            y, 
  30.                            1, 
  31.                            GDK_BUTTON1_MASK, 
  32.                            GDK_BUTTON_PRESS); 
  33.   ttt_functional_test_util_reaction_time(); 
  34.   gdk_test_simulate_button(window, 
  35.                            x, 
  36.                            y, 
  37.                            1, 
  38.                            GDK_BUTTON1_MASK, 
  39.                            GDK_BUTTON_RELEASE); 
  40.   ttt_functional_test_util_reaction_time(); 
  41.   ttt_functional_test_util_reaction_time_long(); 
  42.   return(TRUE); 

我們想要保證按鈕處于激活狀態,因此我們提供一個空閑條件函數:

  1. gboolean 
  2. ttt_functional_test_util_idle_test_toggle_active( 
  3.      GtkToggleButton **toggle_button) 
  4.   gboolean do_idle; 
  5.   do_idle = TRUE
  6.   gdk_threads_enter(); 
  7.   if(*toggle_button != NULL && 
  8.      GTK_IS_TOGGLE_BUTTON(*toggle_button) && 
  9.      gtk_toggle_button_get_active(*toggle_button)){ 
  10.     do_idle = FALSE
  11.   } 
  12.   gdk_threads_leave(); 
  13.   return(do_idle); 

測試場景

因為這個 Tictactoe 程序非常簡單,我們只需要確保點擊了一個 GtkToggleButton 按鈕即可。一旦該按鈕肯定進入了激活狀態,功能測試就可以執行。為了點擊按鈕,我們使用上面提到的很方便的 util 函數。

如圖所示,我們假設,填滿***行,玩家 A 就贏,因為玩家 B 沒有注意,只填充了第二行。

  1. GtkWindow *window; 
  2. Tictactoe *ttt; 
  3. void* 
  4. ttt_functional_test_gtk_main(void *) 
  5.   gtk_main(); 
  6.   pthread_exit(NULL); 
  7. void 
  8. ttt_functional_test_dumb_player_b() 
  9.   GtkButton *buttons[3][3]; 
  10.   guint i; 
  11.   /* to avoid race-conditions copy the buttons */ 
  12.   gdk_threads_enter(); 
  13.   memcpy(buttons, ttt->buttons, 9 * sizeof(GtkButton *)); 
  14.   gdk_threads_leave(); 
  15.   /* TEST 1 - the dumb player B */ 
  16.   for(i = 0; i < 3; i++){ 
  17.     /* assert player A clicks the button successfully */ 
  18.     if(!ttt_functional_test_util_button_click(buttons[0][i])){ 
  19.       exit(-1); 
  20.     } 
  21.     functional_test_util_idle_condition_and_timeout( 
  22.          ttt_functional_test_util_idle_test_toggle_active, 
  23.          ttt_functional_test_util_default_timeout, 
  24.          &buttons[0][i]); 
  25.     /* assert player B clicks the button successfully */ 
  26.     if(!ttt_functional_test_util_button_click(buttons[1][i])){ 
  27.       exit(-1); 
  28.     } 
  29.     functional_test_util_idle_condition_and_timeout( 
  30.          ttt_functional_test_util_idle_test_toggle_active, 
  31.          ttt_functional_test_util_default_timeout, 
  32.          &buttons[1][i]); 
  33.   } 
  34. int 
  35. main(int argc, char **argv) 
  36.   pthread_t thread; 
  37.   gtk_init(&argc, &argv); 
  38.   /* start the tictactoe application */ 
  39.   window = gtk_window_new(GTK_WINDOW_TOPLEVEL); 
  40.   ttt = tictactoe_new(); 
  41.   gtk_container_add(window, ttt); 
  42.   gtk_widget_show_all(window); 
  43.   /* start the Gtk+ dispatcher */ 
  44.   pthread_create(&thread, NULL
  45.                  ttt_functional_test_gtk_main, NULL); 
  46.   /* launch test routines */ 
  47.   ttt_functional_test_dumb_player_b(); 
  48.   /* terminate the application */ 
  49.   gdk_threads_enter(); 
  50.   gtk_main_quit(); 
  51.   gdk_threads_leave(); 
  52.   return(0); 

(題圖:opensource.com)

 

責任編輯:龐桂玉 來源: Linux中國
相關推薦

2009-03-18 14:42:23

LinuxGTK+ 2.16.0發布

2009-07-08 14:32:10

GTK+嵌入式Linux

2010-08-24 16:07:37

C語言

2013-05-15 10:27:05

R語言

2020-12-30 08:50:15

Font ManageLinux開源

2009-02-16 09:10:00

ChromeLinuxGTK

2011-05-13 15:46:49

C模塊化

2014-07-15 11:16:17

Go語言

2014-04-11 09:45:15

2019-07-29 09:19:26

編程語言PythonJava

2010-05-18 11:04:11

MySQL數據庫

2011-08-31 17:55:06

2023-09-03 23:49:35

2019-09-29 09:40:20

LinuxWindowsMacOS

2009-10-23 12:53:25

VB.NET語言

2021-02-03 13:56:09

KerasAPI深度學習

2009-10-09 18:21:32

服務器測試

2015-08-18 09:31:12

圖標AB測試

2020-06-12 10:46:18

C語言棧內存結構體

2010-10-27 10:19:33

UnicodeJava
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 久久久久成人精品亚洲国产 | 久久国产精品一区二区三区 | 亚洲精品成人 | 免费在线观看黄视频 | 91精品国产一二三 | 日韩欧美在线精品 | 九九九色 | 精品免费国产 | 亚洲电影一区二区三区 | 久久伊人青青草 | 日韩二三区 | 毛片在线免费播放 | 欧美日韩精品久久久免费观看 | 色又黄又爽网站www久久 | 久久国产免费看 | 欧美一区二区三区精品 | 亚洲视屏| 欧美v免费| 天天艹 | 中日韩毛片 | 成人亚洲视频 | 精品一区二区三区在线观看 | 日韩精品一区二区三区视频播放 | 婷婷色国产偷v国产偷v小说 | 久久久久久久成人 | 国产婷婷精品av在线 | 爱爱视频日本 | 日韩精品无码一区二区三区 | 精品久久久久久久久久久久久久 | 色网站入口 | 亚洲国产高清免费 | www.狠狠干| 岛国av免费观看 | 古装三级在线播放 | 久久69精品久久久久久久电影好 | 性色的免费视频 | 国产精品久久99 | 中文字幕免费中文 | 99re99| 夜夜爽99久久国产综合精品女不卡 | 国产日韩精品在线 |