]> granicus.if.org Git - check/commitdiff
Selective testing support in run_test_*
authorjemarch <jemarch@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Thu, 18 Feb 2010 19:37:32 +0000 (19:37 +0000)
committerjemarch <jemarch@64e312b2-a51f-0410-8e61-82d0ca0eb02a>
Thu, 18 Feb 2010 19:37:32 +0000 (19:37 +0000)
git-svn-id: svn+ssh://svn.code.sf.net/p/check/code/trunk@584 64e312b2-a51f-0410-8e61-82d0ca0eb02a

ChangeLog
doc/check.texi
src/check.c
src/check.h.in
src/check_run.c
tests/Makefile.am
tests/check_check_main.c
tests/check_check_selective.c [new file with mode: 0644]

index 3a601cda5e02c23910e903cc6a5b64721c4f25cb..11e2bfd84d5f74c9aefb2da155b19b1b3cd19983 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,47 @@
+2010-02-17  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * tests/check_check_selective.c (make_selective_suite): New
+       function.
+       (selective_setup): New function.
+       (selective_teardown): New function.
+       New tests 'test_srunner_run_run_all, 'test_srunner_run_suite',
+       'test_srunner_run_no_suite', test_srunner_run_tcase',
+       'test_srunner_no_tcase', 'test_srunner_suite_tcase',
+       'test_srunner_suite_no_tcase', 'test_srunner_run_suite_env',
+       'test_srunner_run_no_suite_env', 'test_srunner_run_tcase_env',
+       'test_srunner_run_no_tcase_env', 'test_srunner_suite_tcase_env',
+       'test_srunner_suite_no_tcase_env'.
+
+       * tests/Makefile.am (check_check_SOURCES): Add
+       'check_check_selective.c'.
+
+       * tests/check_check_selective.c: New file.
+
+       * tests/check_check_main.c (main): Add the selective_suite to the
+       master suite.
+
+2010-02-10  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * doc/check.texi (SRunner Output): Document 'srunner_run' and the
+       usage of CK_RUN_CASE and CK_RUN_SUITE environment variables.
+
+       * src/check_run.c (srunner_run): Use values of environment
+       variables CK_RUN_CASE and CK_RUN_SUITE.
+
+2010-02-02  Jose E. Marchesi  <jemarch@gnu.org>
+
+       * src/check.c (suite_tcase): New function that determines whether
+       a a given test suite contains a test case named after a given
+       string.
+
+       * src/check_run.c (srunner_run): New function, renamed from
+       'srunner_run_all', allowing selective running of an specific test
+       suite and/or test case.
+       (srunner_run_all): New function, invoking srunner_run internally
+       to provide backwards compatibility.
+
+       * src/check.h.in: Add prototype for srunner_run.
+
 2005-12-16 hugo303
 
        * src/check_pack.c: Fixed buggy eprintf string.
index 19dd874b46b9cfeb96fdab23bd68d5353821b122..fa6a7920f524644c0cae938afd889768597fe384 100644 (file)
@@ -638,22 +638,38 @@ focus on making the test pass.
 @section SRunner Output
 
 @findex srunner_run_all()
-The function to run tests in an @code{SRunner} is defined as follows:
+@findex srunner_run()
+The functions to run tests in an @code{SRunner} are defined as follows:
 @example
 @verbatim
 void srunner_run_all (SRunner * sr, enum print_output print_mode);
+
+void srunner_run (SRunner *sr, const char *sname, const char *tcname,
+                  enum print_output print_mode);
 @end verbatim
 @end example
 
-This function does two things:
+Those functions do two things:
 
 @enumerate
 @item
-It runs all of the unit tests for all of the test cases defined for all
-of the suites in the SRunner, and collects the results in the SRunner
+They run all of the unit tests for the selected test cases defined for
+the selected suites in the SRunner, and collect the results in the
+SRunner.  The determination of the selected test cases and suites
+depends on the specific function used.
+
+@code{srunner_run_all} will run all the defined test cases of all
+defined suites except if the environment variables @code{CK_RUN_CASE}
+or @code{CK_RUN_SUITE} are defined.  If defined, those variables shall
+contain the name of a test suite or a test case, defining in that way
+the selected suite/test case.
+
+@code{srunner_run} will run the suite/case selected by the
+@code{sname} and @code{tcname} parameters.  A value of @code{NULL}
+in some of those parameters means ``any suite/case''.
 
 @item
-It prints the results according to the @code{print_mode} specified.
+They print the results according to the @code{print_mode} specified.
 @end enumerate
 
 For SRunners that have already been run, there is also a separate
index 41b9e793cd8c0e85261c1537bc10ad7aec7cb375..1126dd4032238222ed87590c61396ac2a44c76c2 100644 (file)
@@ -59,6 +59,24 @@ Suite *suite_create (const char *name)
   return s;
 }
 
+int suite_tcase (Suite *s, const char *tcname)
+{
+  List *l;
+  TCase *tc;
+
+  if (s == NULL)
+    return 0;
+
+  l = s->tclst;
+  for (list_front (l); !list_at_end (l); list_advance (l)) {
+    tc = list_val (l);
+    if (strcmp (tcname, tc->name) == 0)
+      return 1;
+  }
+
+  return 0;
+}
+
 static void suite_free (Suite *s)
 {
   List *l;
index 231fdbb568024c5807e89a970f2db5497a4ee90e..81434557a101823aa74ef9c754836438e757a381 100644 (file)
@@ -120,6 +120,10 @@ typedef struct Suite Suite;
 /* Creates a test suite with the given name */
 Suite * CK_EXPORT suite_create (const char *name);
 
+/* Determines whether a given test suite contains a case named after a
+   given string.  */
+int suite_tcase (Suite *s, const char *tcname);
+
 /* Add a test case to a suite */
 void CK_EXPORT suite_add_tcase (Suite *s, TCase *tc);
 
@@ -328,6 +332,11 @@ void CK_EXPORT srunner_free (SRunner *sr);
 /* Runs an SRunner, printing results as specified (see enum print_output) */
 void CK_EXPORT srunner_run_all (SRunner *sr, enum print_output print_mode);
 
+/* Runs an SRunner specifying test suite and test case by name,
+   printing results as specified (see enum print_output).  A NULL
+   value means "any test suite" or "any test case".  */
+void CK_EXPORT srunner_run (SRunner *sr, const char *sname, const char *tcname, enum print_output print_mode);
+
  
 /* Next functions are valid only after the suite has been
    completely run, of course */
index 374bf4a0c7ad26402c21f480a02926a0373ec172..92ac9377b65a8fbed84697d0c3f9abacce71580e 100644 (file)
@@ -54,6 +54,7 @@ enum tf_type {
 static void srunner_run_init (SRunner *sr, enum print_output print_mode);
 static void srunner_run_end (SRunner *sr, enum print_output print_mode);
 static void srunner_iterate_suites (SRunner *sr,
+                                    const char *sname, const char *tcname,
                                    enum print_output print_mode);
 static void srunner_iterate_tcase_tfuns (SRunner *sr, TCase *tc);
 static void srunner_add_failure (SRunner *sr, TestResult *tf);
@@ -120,6 +121,7 @@ static void srunner_run_end (SRunner *sr, enum print_output CK_ATTRIBUTE_UNUSED
 }
 
 static void srunner_iterate_suites (SRunner *sr,
+                                    const char *sname, const char *tcname,
                                    enum print_output CK_ATTRIBUTE_UNUSED print_mode)
   
 {
@@ -128,16 +130,25 @@ static void srunner_iterate_suites (SRunner *sr,
   TCase *tc;
 
   slst = sr->slst;
-  
+
   for (list_front(slst); !list_at_end(slst); list_advance(slst)) {
     Suite *s = list_val(slst);
     
+    if (((sname != NULL) && (strcmp (sname, s->name) != 0))
+        || ((tcname != NULL) && (!suite_tcase (s, tcname))))
+      continue;
+
     log_suite_start (sr, s);
 
     tcl = s->tclst;
   
     for (list_front(tcl);!list_at_end (tcl); list_advance (tcl)) {
       tc = list_val (tcl);
+
+      if ((tcname != NULL) && (strcmp (tcname, tc->name) != 0)) {
+          continue;
+        }
+
       srunner_run_tcase (sr, tc);
     }
     
@@ -513,12 +524,25 @@ void srunner_set_fork_status (SRunner *sr, enum fork_status fstat)
 }
 
 void srunner_run_all (SRunner *sr, enum print_output print_mode)
+{
+  srunner_run (sr,
+               NULL,  /* All test suites.  */
+               NULL,  /* All test cases.   */
+               print_mode);
+}
+
+void srunner_run (SRunner *sr, const char *sname, const char *tcname, enum print_output print_mode)
 {
 #ifdef _POSIX_VERSION
   struct sigaction old_action;
   struct sigaction new_action;
 #endif /* _POSIX_VERSION */
 
+  /*  Get the selected test suite and test case from the
+      environment.  */
+  if (!tcname) tcname = getenv ("CK_RUN_CASE");
+  if (!sname) sname = getenv ("CK_RUN_SUITE");
+
   if (sr == NULL)
     return;
   if (print_mode >= CK_LAST)
@@ -532,7 +556,7 @@ void srunner_run_all (SRunner *sr, enum print_output print_mode)
   sigaction(SIGALRM, &new_action, &old_action);
 #endif /* _POSIX_VERSION */
   srunner_run_init (sr, print_mode);
-  srunner_iterate_suites (sr, print_mode);
+  srunner_iterate_suites (sr, sname, tcname, print_mode);
   srunner_run_end (sr, print_mode);
 #ifdef _POSIX_VERSION
   sigaction(SIGALRM, &old_action, NULL);
index 0e8ddc70c0f7bccb24637f6f99ac1e6b2406a9cf..a68439a98933fd7ca33c365f86ee90687e69462c 100644 (file)
@@ -53,6 +53,7 @@ check_check_SOURCES = \
        check_check_fixture.c           \
        check_check_pack.c              \
        check_check_exit.c              \
+        check_check_selective.c         \
        check_check_main.c
 check_check_LDADD = $(top_builddir)/src/libcheckinternal.la $(top_builddir)/lib/libcompat.la
 
index 692a96dda7c6110ce99ad898d16c9e42e09483c3..b0b66cc20ee7525caf431f0d78631bfeef7470e5 100644 (file)
@@ -26,6 +26,7 @@ int main (void)
   srunner_add_suite(sr, make_fixture_suite());
   srunner_add_suite(sr, make_pack_suite());
   srunner_add_suite(sr, make_exit_suite());
+  srunner_add_suite(sr, make_selective_suite());
   
   printf ("Ran %d tests in subordinate suite\n", sub_ntests);
   srunner_run_all (sr, CK_VERBOSE);
diff --git a/tests/check_check_selective.c b/tests/check_check_selective.c
new file mode 100644 (file)
index 0000000..b2f6f76
--- /dev/null
@@ -0,0 +1,331 @@
+#include "../lib/libcompat.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <check.h>
+#include "check_check.h"
+
+static SRunner *sr;
+static int test_tc11_executed;
+static int test_tc12_executed;
+static int test_tc21_executed;
+
+static void reset_executed (void)
+{
+  test_tc11_executed = 0;
+  test_tc12_executed = 0;
+  test_tc21_executed = 0;
+}
+
+START_TEST(test_tc11)
+{
+  test_tc11_executed = 1;
+}
+END_TEST
+
+START_TEST(test_tc12)
+{
+  test_tc12_executed = 1;
+}
+END_TEST
+
+START_TEST(test_tc21)
+{
+  test_tc21_executed = 1;
+}
+END_TEST
+
+static void selective_setup (void)
+{
+  Suite *s1, *s2;
+  TCase *tc11, *tc12, *tc21;
+
+  /*
+   * Create a test suite 'suite1' with two test cases 'tcase11' and
+   * 'tcase12' containing a single test each.
+   */
+  s1 = suite_create ("suite1");
+  tc11 = tcase_create ("tcase11");
+  tcase_add_test (tc11, test_tc11);
+  tc12 = tcase_create ("tcase12");
+  tcase_add_test (tc12, test_tc12);
+  suite_add_tcase (s1, tc11);
+  suite_add_tcase (s1, tc12);
+  
+  /*
+   * Create a test suite 'suite2' with one test case 'test21'
+   * containing two tests.
+   */
+  s2 = suite_create ("suite2");
+  tc21 = tcase_create ("tcase21");
+  tcase_add_test (tc21, test_tc21);
+  suite_add_tcase (s2, tc21);
+
+  sr = srunner_create (s1);
+  srunner_add_suite (sr, s2);
+  srunner_set_fork_status (sr, CK_NOFORK);
+}
+
+static void selective_teardown (void)
+{
+  srunner_free (sr);
+}
+
+
+START_TEST(test_srunner_run_run_all)
+{
+  /* This test exercises the srunner_run function for the case where
+     both sname and tcname are NULL.  That means to run all the test
+     cases in all the defined suites.  */
+  srunner_run (sr,
+               NULL, /* NULL tsuite name.  */
+               NULL, /* NULL tcase name.  */
+               CK_VERBOSE);
+
+  fail_unless (srunner_ntests_run(sr) == 3,
+               "Not all tests were executed.");
+
+  reset_executed ();
+}
+END_TEST
+
+START_TEST(test_srunner_run_suite)
+{
+  /* This test makes the srunner_run function to run all the test
+     cases of a existing suite.  */
+  srunner_run (sr,
+               "suite1",
+               NULL,  /* NULL tcase name.  */
+               CK_VERBOSE);
+
+  fail_unless (test_tc11_executed 
+               && test_tc12_executed
+               && !test_tc21_executed,
+               "Expected tests were not executed.");
+
+  reset_executed ();
+}
+END_TEST
+
+START_TEST(test_srunner_run_no_suite)
+{
+  /* This test makes the srunner_run function to run all the test
+     cases of a non-existing suite.  */
+  srunner_run (sr,
+               "non-existing-suite",
+               NULL, /* NULL tcase name. */
+               CK_VERBOSE);
+  
+  fail_if (test_tc11_executed
+           || test_tc12_executed
+           || test_tc21_executed,
+           "An unexpected test was executed.");
+
+  reset_executed ();
+}
+END_TEST
+
+START_TEST(test_srunner_run_tcase)
+{
+  /* This test makes the srunner_run function to run an specific
+     existing test case.  */
+  srunner_run (sr,
+               NULL,  /* NULL suite name.  */
+               "tcase12",
+               CK_VERBOSE);
+
+  fail_unless (!test_tc11_executed
+               && test_tc12_executed
+               && !test_tc21_executed,
+               "Expected tests were not executed.");
+  
+  reset_executed ();
+}
+END_TEST
+
+START_TEST(test_srunner_no_tcase)
+{
+  /* This test makes the srunner_run function to run a non-existant
+     test case.  */
+  srunner_run (sr,
+               NULL,  /* NULL suite name.  */
+               "non-existant-test-case",
+               CK_VERBOSE);
+
+  fail_if (test_tc11_executed
+           || test_tc12_executed
+           || test_tc21_executed,
+           "An unexpected test was executed.");
+
+  reset_executed ();
+}
+END_TEST
+
+START_TEST(test_srunner_suite_tcase)
+{
+  /* This test makes the srunner_run function to run a specific test
+     case of a specific test suite.  */
+  srunner_run (sr,
+               "suite2",
+               "tcase21",
+               CK_VERBOSE);
+  
+  fail_unless (!test_tc11_executed
+               && !test_tc12_executed
+               && test_tc21_executed,
+               "Expected tests were not executed.");
+
+  reset_executed ();
+}
+END_TEST
+
+START_TEST(test_srunner_suite_no_tcase)
+{
+  /* This test makes the srunner_run function to run a non existant
+     test case of a specific test suite.  */
+  srunner_run (sr,
+               "suite1",
+               "non-existant-test-case",
+               CK_VERBOSE);
+
+  fail_if (test_tc11_executed
+           || test_tc12_executed
+           || test_tc21_executed,
+           "An unexpected test was executed.");
+
+  reset_executed ();
+}
+END_TEST
+
+
+START_TEST(test_srunner_run_suite_env)
+{
+  /* This test makes the srunner_run_all function to run all the test
+     cases of a existing suite.  */
+  setenv ("CK_RUN_SUITE", "suite1", 1);
+  srunner_run_all (sr, CK_VERBOSE);
+
+  fail_unless (test_tc11_executed 
+               && test_tc12_executed
+               && !test_tc21_executed,
+               "Expected tests were not executed.");
+
+  reset_executed ();
+  unsetenv ("CK_RUN_SUITE");
+}
+END_TEST
+
+START_TEST(test_srunner_run_no_suite_env)
+{
+  /* This test makes the srunner_run_all function to run all the test
+     cases of a non-existing suite.  */
+  setenv ("CK_RUN_SUITE", "non-existing-suite", 1);
+  srunner_run_all (sr, CK_VERBOSE);
+  
+  fail_if (test_tc11_executed
+           || test_tc12_executed
+           || test_tc21_executed,
+           "An unexpected test was executed.");
+
+  reset_executed ();
+  unsetenv ("CK_RUN_SUITE");
+}
+END_TEST
+
+START_TEST(test_srunner_run_tcase_env)
+{
+  /* This test makes the srunner_run_all function to run an specific
+     existing test case.  */
+  setenv ("CK_RUN_CASE", "tcase12", 1);
+  srunner_run_all (sr, CK_VERBOSE);
+
+  fail_unless (!test_tc11_executed
+               && test_tc12_executed
+               && !test_tc21_executed,
+               "Expected tests were not executed.");
+  
+  reset_executed ();
+  unsetenv ("CK_RUN_CASE");
+}
+END_TEST
+
+START_TEST(test_srunner_no_tcase_env)
+{
+  /* This test makes the srunner_run_all function to run a
+     non-existant test case.  */
+  setenv ("CK_RUN_CASE", "non-existant-test-case", 1);
+  srunner_run_all (sr, CK_VERBOSE);
+
+  fail_if (test_tc11_executed
+           || test_tc12_executed
+           || test_tc21_executed,
+           "An unexpected test was executed.");
+
+  reset_executed ();
+  unsetenv ("CK_RUN_CASE");
+}
+END_TEST
+
+START_TEST(test_srunner_suite_tcase_env)
+{
+  /* This test makes the srunner_run_all function to run a specific test
+     case of a specific test suite.  */
+  setenv ("CK_RUN_SUITE", "suite2", 1);
+  setenv ("CK_RUN_CASE", "tcase21", 1);
+  srunner_run_all (sr, CK_VERBOSE);
+  
+  fail_unless (!test_tc11_executed
+               && !test_tc12_executed
+               && test_tc21_executed,
+               "Expected tests were not executed.");
+
+  reset_executed ();
+  unsetenv ("CK_RUN_SUITE");
+  unsetenv ("CK_RUN_CASE");
+}
+END_TEST
+
+START_TEST(test_srunner_suite_no_tcase_env)
+{
+  /* This test makes the srunner_run_all function to run a non
+     existant test case of a specific test suite.  */
+  setenv ("CK_RUN_SUITE", "suite1", 1);
+  setenv ("CK_RUN_CASE", "non-existant-test-case", 1);
+  srunner_run_all (sr, CK_VERBOSE);
+
+  fail_if (test_tc11_executed
+           || test_tc12_executed
+           || test_tc21_executed,
+           "An unexpected test was executed.");
+
+  reset_executed ();
+  unsetenv ("CK_RUN_SUITE");
+  unsetenv ("CK_RUN_CASE");
+}
+END_TEST
+
+Suite *make_selective_suite (void)
+{
+  Suite *s = suite_create ("SelectiveTesting");
+  TCase *tc = tcase_create ("Core");
+
+  suite_add_tcase (s, tc);
+  tcase_add_test (tc, test_srunner_run_run_all);
+  tcase_add_test (tc, test_srunner_run_suite);
+  tcase_add_test (tc, test_srunner_run_no_suite);
+  tcase_add_test (tc, test_srunner_run_tcase);
+  tcase_add_test (tc, test_srunner_no_tcase);
+  tcase_add_test (tc, test_srunner_suite_tcase);
+  tcase_add_test (tc, test_srunner_suite_no_tcase);
+  tcase_add_test (tc, test_srunner_run_suite_env);
+  tcase_add_test (tc, test_srunner_run_no_suite_env);
+  tcase_add_test (tc, test_srunner_run_tcase_env);
+  tcase_add_test (tc, test_srunner_no_tcase_env);
+  tcase_add_test (tc, test_srunner_suite_tcase_env);
+  tcase_add_test (tc, test_srunner_suite_no_tcase_env);
+
+  tcase_add_unchecked_fixture (tc,
+                               selective_setup,
+                               selective_teardown);
+  return s;
+}