博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
gtk+程序_用C功能测试Gtk +应用程序
阅读量:2527 次
发布时间:2019-05-11

本文共 12070 字,大约阅读时间需要 40 分钟。

gtk+程序

需要进行自动测试以确保程序的质量并按预期工作。 单元测试仅检查算法的某些部分,而不关注每个组件如何组合在一起。 这就是功能测试(有时称为集成测试)的来源。

功能测试基本上是通过网站还是桌面应用程序与您的用户界面进行交互。 为了向您展示它的工作原理,让我们看一下如何测试Gtk +应用程序。 为简单起见,在本教程中,我们使用Gtk + 2.0教程中的示例。

基本设定

对于每个功能测试,通常都定义一些全局变量,例如“用户交互延迟”或“直到指示失败为止的超时”(即,直到指定的时间并且应用程序注定要发生事件时)。

#define TTT_FUNCTIONAL_TEST_UTIL_IDLE_CONDITION(f) ((TttFunctionalTestUtilIdleCondition)(f))      
#define TTT_FUNCTIONAL_TEST_UTIL_REACTION_TIME (125000)
#define TTT_FUNCTIONAL_TEST_UTIL_REACTION_TIME_LONG (500000)
typedef gboolean
(
* TttFunctionalTestUtilIdleCondition
)
( gpointer data
)
;
struct timespec ttt_functional_test_util_default_timeout
=
{
 
20
,
 
0
,
}
;

现在我们可以实现停滞时间功能。 在这里,我们将使用usleep函数以获得所需的延迟。

void      
ttt_functional_test_util_reaction_time
(
)
{
  usleep
( TTT_FUNCTIONAL_TEST_UTIL_REACTION_TIME
)
;
}
void
ttt_functional_test_util_reaction_time_long
(
)
{
  usleep
( TTT_FUNCTIONAL_TEST_UTIL_REACTION_TIME_LONG
)
;
}

超时功能将延迟执行,直到应用控件的状态为止。 这对于异步应用的动作很有用,这就是为什么它会延迟较长时间的原因。

void      
ttt_functional_test_util_idle_condition_and_timeout
(
     TttFunctionalTestUtilIdleCondition idle_condition
,
     
struct timespec
* timeout
,
     pointer data
)
{
 
struct timespec start_time
, current_time
;
  clock_gettime
( CLOCK_MONOTONIC
,
               
& start_time
)
;
 
while
( TTT_FUNCTIONAL_TEST_UTIL_IDLE_CONDITION
( idle_condition
)
( data
)
)
{
    ttt_functional_test_util_reaction_time
(
)
;
    clock_gettime
( CLOCK_MONOTONIC
,
                 
& current_time
)
;
   
if
( start_time.
tv_sec
+ timeout
-> tv_sec
< current_time.
tv_sec
)
{
     
break
;
   
}
 
}
  ttt_functional_test_util_reaction_time
(
)
;
}

与图形用户界面进行交互

为了模拟用户交互, 提供了我们需要的功能。 要在这里进行工作,我们仅需要以下三个功能:

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

例如,要测试按钮单击,我们执行以下操作:

gboolean     
ttt_functional_test_util_button_click
( GtkButton
* button
)
{
  GtkWidget
* widget
;
  GdkWindow
* window
;
  gint x
, y
;
  gint origin_x
, origin_y
;
 
if
( button
== NULL
||
     
! GTK_IS_BUTTON
( button
)
)
{
   
return
( FALSE
)
;
 
}
  widget
= button
;
 
if
(
! GTK_WIDGET_REALIZED
( widget
)
)
{
    ttt_functional_test_util_reaction_time_long
(
)
;
 
}
 
/* retrieve window and pointer position */
  gdk_threads_enter
(
)
;
  window
= gtk_widget_get_window
( widget
)
;
  x
= widget
-> allocation.
x
+ widget
-> allocation.
width
/
2.0
;
  y
= widget
-> allocation.
y
+ widget
-> allocation.
height
/
2.0
;
  gdk_window_get_origin
( window
,
& origin_x
,
& origin_y
)
;
  gdk_display_warp_pointer
( gtk_widget_get_display
( widget
)
,
                           gtk_widget_get_screen
( widget
)
,
                           origin_x
+ x
, origin_y
+ y
)
;
  gdk_threads_leave
(
)
;
 
/* click the button */
  ttt_functional_test_util_reaction_time
(
)
;
  gdk_test_simulate_button
( window
,
                           x
,
                           y
,
                           
1
,
                           GDK_BUTTON1_MASK
,
                           GDK_BUTTON_PRESS
)
;
  ttt_functional_test_util_reaction_time
(
)
;
  gdk_test_simulate_button
( window
,
                           x
,
                           y
,
                           
1
,
                           GDK_BUTTON1_MASK
,
                           GDK_BUTTON_RELEASE
)
;
  ttt_functional_test_util_reaction_time
(
)
;
  ttt_functional_test_util_reaction_time_long
(
)
;
 
return
( TRUE
)
;
}

我们要确保按钮处于活动状态,因此我们提供了一个空闲条件功能:

gboolean     
ttt_functional_test_util_idle_test_toggle_active
(
     GtkToggleButton
** toggle_button
)
{
  gboolean do_idle
;
  do_idle
= TRUE
;
  gdk_threads_enter
(
)
;
 
if
(
* toggle_button
!= NULL
&&
     GTK_IS_TOGGLE_BUTTON
(
* toggle_button
)
&&
     gtk_toggle_button_get_active
(
* toggle_button
)
)
{
    do_idle
= FALSE
;
 
}
  gdk_threads_leave
(
)
;
 
return
( do_idle
)
;
}

测试场景

由于Tictactoe程序非常简单,因此我们只需要确保单击了 。 一旦断言按钮进入活动状态,功能测试就可以继续进行。 要单击按钮,我们使用上面提供的方便的util函数。

为了说明起见,我们假设玩家A通过填充第一行立即获胜,因为玩家B没有注意,只是填充了第二行:

GtkWindow      
* window
;
Tictactoe
* ttt
;
void
*
ttt_functional_test_gtk_main
(
void
*
)
{
  gtk_main
(
)
;
  pthread_exit
( NULL
)
;
}
void
ttt_functional_test_dumb_player_b
(
)
{
  GtkButton
* buttons
[
3
]
[
3
]
;
  guint i
;
 
 
/* to avoid race-conditions copy the buttons */
  gdk_threads_enter
(
)
;
 
 
( buttons
, ttt
-> buttons
,
9
*
sizeof
( GtkButton
*
)
)
;
  gdk_threads_leave
(
)
;
 
/* TEST 1 - the dumb player B */
 
for
( i
=
0
; i
<
3
; i
++
)
{
   
/* assert player A clicks the button successfully */
   
if
(
! ttt_functional_test_util_button_click
( buttons
[
0
]
[ i
]
)
)
{
     
(
-
1
)
;
   
}
    functional_test_util_idle_condition_and_timeout
(
         ttt_functional_test_util_idle_test_toggle_active
,
         ttt_functional_test_util_default_timeout
,
         
& buttons
[
0
]
[ i
]
)
;
   
/* assert player B clicks the button successfully */
   
if
(
! ttt_functional_test_util_button_click
( buttons
[
1
]
[ i
]
)
)
{
     
(
-
1
)
;
   
}
    functional_test_util_idle_condition_and_timeout
(
         ttt_functional_test_util_idle_test_toggle_active
,
         ttt_functional_test_util_default_timeout
,
         
& buttons
[
1
]
[ i
]
)
;
 
}
}
int
main
(
int argc
,
char
** argv
)
{
  pthread_t thread
;
  gtk_init
(
& argc
,
& argv
)
;
                 
 
/* start the tictactoe application */
  window
= gtk_window_new
( GTK_WINDOW_TOPLEVEL
)
;
  ttt
= tictactoe_new
(
)
;
  gtk_container_add
( window
, ttt
)
;
  gtk_widget_show_all
( window
)
;
 
/* start the Gtk+ dispatcher */
  pthread_create
(
& thread
, NULL
,
                 ttt_functional_test_gtk_main
, NULL
)
;
 
/* launch test routines */
  ttt_functional_test_dumb_player_b
(
)
;
 
/* terminate the application */
  gdk_threads_enter
(
)
;
  gtk_main_quit
(
)
;
 
  gdk_threads_leave
(
)
;
 
return
(
0
)
;
}

翻译自:

gtk+程序

转载地址:http://pgszd.baihongyu.com/

你可能感兴趣的文章
Hive实现oracle的Minus函数
查看>>
秒杀多线程第四篇 一个经典的多线程同步问题
查看>>
RocketMQ配置
查看>>
vs code调试console程序报错--preLaunchTask“build”
查看>>
蚂蚁金服井贤栋:用技术联手金融机构,形成服务小微的生态合力
查看>>
手机通话记录统计分析
查看>>
富文本编辑器比较
查看>>
端口号大全
查看>>
机器学习基石笔记2——在何时可以使用机器学习(2)
查看>>
POJ 3740 Easy Finding (DLX模板)
查看>>
MySQL 处理重复数据
查看>>
关于typedef的用法总结(转)
查看>>
hibernate could not resolve property
查看>>
【strtok()】——分割字符串
查看>>
Linux下安装rabbitmq
查看>>
曹德旺
查看>>
【转】判断点在多边形内(matlab)
查看>>
java基础之集合:List Set Map的概述以及使用场景
查看>>
Python 线程 进程 协程
查看>>
骨牌覆盖问题
查看>>