diff --git a/cmake/modules/DunePerftoolMacros.cmake b/cmake/modules/DunePerftoolMacros.cmake
index 9a361de7e01061c14e4c973a6a8a90aff3128612..e2d7d1f2ef91378cba56466f6868c6d6c8e1596f 100644
--- a/cmake/modules/DunePerftoolMacros.cmake
+++ b/cmake/modules/DunePerftoolMacros.cmake
@@ -115,3 +115,5 @@ function(add_generated_executable)
 
   add_dependencies(generation ${GEN_TARGET})
 endfunction()
+
+include(GeneratedSystemtests)
\ No newline at end of file
diff --git a/cmake/modules/GeneratedSystemtests.cmake b/cmake/modules/GeneratedSystemtests.cmake
new file mode 100644
index 0000000000000000000000000000000000000000..f9c085447ec30c79d63e3921fb323c1c08a091f8
--- /dev/null
+++ b/cmake/modules/GeneratedSystemtests.cmake
@@ -0,0 +1,76 @@
+# System testing for generated executables. All ideas taken from dune-testtools.
+#
+
+function(dune_add_formcompiler_system_test)
+  # parse arguments
+  set(OPTION DEBUG)
+  set(SINGLE INIFILE BASENAME SCRIPT UFLFILE)
+  set(MULTI CREATED_TARGETS)
+  cmake_parse_arguments(SYSTEMTEST "${OPTION}" "${SINGLE}" "${MULTI}" ${ARGN})
+
+  if(SYSTEMTEST_UNPARSED_ARGUMENTS)
+    message(WARNING "dune_add_system_test: Encountered unparsed arguments: This often indicates typos in named arguments")
+  endif()
+
+  # construct a string containg DEBUG to pass the debug flag to the other macros
+  set(DEBUG "")
+  if(SYSTEMTEST_DEBUG)
+    set(DEBUG "DEBUG")
+  endif()
+
+  # set a default for the script. call_executable.py just calls the executable.
+  # There, it is also possible to hook in things depending on the inifile
+  if(NOT SYSTEMTEST_SCRIPT)
+    set(SYSTEMTEST_SCRIPT dune_execute.py)
+  endif()
+
+  # we provide two signatures: either a source(s) is given or a target(s)
+  if(NOT SYSTEMTEST_UFLFILE)
+    message(FATAL_ERROR "UFLFILE must be given for dune_add_generated_system_test!")
+  endif()
+
+  # Configure a bogus file from the meta ini file. This is a trick to retrigger configuration on meta ini changes.
+  configure_file(${CMAKE_CURRENT_SOURCE_DIR}/${SYSTEMTEST_INIFILE} ${CMAKE_CURRENT_BINARY_DIR}/tmp_${SYSTEMTEST_INIFILE})
+
+  # expand the given meta ini file into the build tree
+  execute_process(COMMAND ${CMAKE_BINARY_DIR}/dune-env dune_expand_metaini.py --cmake --ini ${CMAKE_CURRENT_SOURCE_DIR}/${SYSTEMTEST_INIFILE} --dir ${CMAKE_CURRENT_BINARY_DIR} --section formcompiler
+                  OUTPUT_VARIABLE output)
+  parse_python_data(PREFIX INIINFO INPUT "${output}")
+
+  foreach(inifile ${INIINFO_names})
+    if(${INIINFO_${inifile}_suffix} STREQUAL "__empty")
+      set(tname ${SYSTEMTEST_BASENAME})
+    else()
+      set(tname ${SYSTEMTEST_BASENAME}_${INIINFO_${inifile}_suffix})
+      if(NOT TARGET ${SYSTEMTEST_BASENAME})
+        add_custom_target(${SYSTEMTEST_BASENAME})
+      endif()
+    endif()
+
+    add_generated_executable(TARGET ${tname}
+                             UFLFILE ${SYSTEMTEST_UFLFILE}
+                             FORM_COMPILER_ARGS --ini-file ${inifile}
+                             )
+
+    # Exclude the target from all
+    set_property(TARGET ${tname} PROPERTY EXCLUDE_FROM_ALL 1)
+
+    # Add dependency on the metatarget for this systemtest
+    if(NOT ${INIINFO_${inifile}_suffix} STREQUAL "__empty")
+      add_dependencies(${SYSTEMTEST_BASENAME} ${tname})
+    endif()
+
+    # and have it depend on the metatarget build_tests
+    add_dependencies(build_tests ${tname})
+
+    _add_test(NAME ${tname}
+              COMMAND ${CMAKE_BINARY_DIR}/dune-env ${SYSTEMTEST_SCRIPT}
+                    --exec ${tname}
+                    --ini "${CMAKE_CURRENT_BINARY_DIR}/${inifile}"
+                    --source ${CMAKE_CURRENT_SOURCE_DIR}
+              )
+
+    set_tests_properties(${tname} PROPERTIES SKIP_RETURN_CODE 77)
+    set_tests_properties(${tname} PROPERTIES TIMEOUT 20)
+  endforeach()
+endfunction()
\ No newline at end of file
diff --git a/python/dune/perftool/options.py b/python/dune/perftool/options.py
index 375d3ab912bea73bd2ad985fda54ba4c08890561..5441bb4714710297acb00803ec5543ecb55b5d9f 100644
--- a/python/dune/perftool/options.py
+++ b/python/dune/perftool/options.py
@@ -66,12 +66,18 @@ def init_option_dict():
         _arguments_read = True
 
         # Read arguments from the given inifile
-        if args["ini_file"]:
+        if _option_dict["ini_file"]:
             from dune.common.parametertree.parser import parse_ini_file
-            inifile = parse_ini_file(args["ini_file"])
-            for key, value in inifile["formcompiler"]:
-                if key not in _option_dict:
+            inifile = parse_ini_file(_option_dict["ini_file"])
+            for key, value in inifile.get("formcompiler", {}).items():
+                if key not in _option_dict or _option_dict[key] is None:
                     _option_dict[key] = value
+                elif not _option_dict[key]:
+                    # As `bool("0")` is True, we need to eval bools
+                    if isinstance(_option_dict[key], bool):
+                        _option_dict[key] = eval(value)
+                    else:
+                        _option_dict[key] = type(_option_dict[key])(value)
 
 
 def set_option(key, value):
diff --git a/test/heatequation/CMakeLists.txt b/test/heatequation/CMakeLists.txt
index 9afc1a3e53d17dedc93242270c01ceb3b7c6c293..7cddb801d7b307261b3ebd208e8115fc9a5d4c9f 100644
--- a/test/heatequation/CMakeLists.txt
+++ b/test/heatequation/CMakeLists.txt
@@ -1,59 +1,24 @@
-#============
-# CG implicit
-#============
-
-add_generated_executable(UFLFILE heatequation.ufl
-                         TARGET heatequation_implicit
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-l2errorsquared 1e-7
-                         )
-
-
-dune_add_system_test(TARGET heatequation_implicit
-                     INIFILE heatequation_implicit.mini
-                     )
-
-#============
-# CG explicit
-#============
-
-add_generated_executable(UFLFILE heatequation.ufl
-                         TARGET heatequation_explicit
-                         FORM_COMPILER_ARGS --explicit-time-stepping --exact-solution-expression g --compare-l2errorsquared 1e-7
-                         )
-
-
-dune_add_system_test(TARGET heatequation_explicit
-                     INIFILE heatequation_explicit.mini
-                     )
-
-#============
-# DG implicit
-#============
-
-add_generated_executable(UFLFILE heatequation_dg.ufl
-                         TARGET heatequation_dg_implicit
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-l2errorsquared 1e-5
-                         )
-
-
-dune_add_system_test(TARGET heatequation_dg_implicit
-                     INIFILE heatequation_dg_implicit.mini
-                     )
-
-#============
-# DG explicit
-#============
-
-add_generated_executable(UFLFILE heatequation_dg.ufl
-                         TARGET heatequation_dg_explicit
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-l2errorsquared 1e-5
-                         )
-
-
-dune_add_system_test(TARGET heatequation_dg_explicit
-                     INIFILE heatequation_dg_explicit.mini
-                     )
-
+#=====
+# CG
+#=====
+
+dune_add_formcompiler_system_test(UFLFILE heatequation.ufl
+                                  BASENAME heatequation
+                                  INIFILE heatequation.mini
+                                  )
+
+#=====
+# DG
+#=====
+
+dune_add_formcompiler_system_test(UFLFILE heatequation_dg.ufl
+                                  BASENAME heatequation_dg
+                                  INIFILE heatequation_dg.mini
+                                  )
+
+#====================
+# Reference solutions
+#====================
 
 # Hand written reference solutions
 add_executable(heatequation_implicit_ref heatequation_implicit_ref.cc)
diff --git a/test/heatequation/heatequation.mini b/test/heatequation/heatequation.mini
new file mode 100644
index 0000000000000000000000000000000000000000..6087d4160a3084387be6fa5af703745893d6dfde
--- /dev/null
+++ b/test/heatequation/heatequation.mini
@@ -0,0 +1,17 @@
+__name = heatequation_{__exec_suffix}
+__exec_suffix = implicit, explicit | expand scheme
+
+lowerleft = 0.0 0.0
+upperright = 1.0 1.0
+elements = 32 32
+elementType = simplical
+
+[wrapper.vtkcompare]
+name = {__name}
+reference = heatequation_ref
+extension = vtu
+
+[formcompiler]
+explicit_time_stepping = 0, 1 | expand scheme
+exact_solution_expression = g
+compare_l2errorsquared = 1e-7
diff --git a/test/heatequation/heatequation_dg.mini b/test/heatequation/heatequation_dg.mini
new file mode 100644
index 0000000000000000000000000000000000000000..e2a455372a077c34f9a46f239da702363a8cdde1
--- /dev/null
+++ b/test/heatequation/heatequation_dg.mini
@@ -0,0 +1,17 @@
+__name = heatequation_dg_{__exec_suffix}
+__exec_suffix = implicit, explicit | expand scheme
+
+lowerleft = 0.0 0.0
+upperright = 1.0 1.0
+elements = 32 32
+elementType = simplical
+
+[wrapper.vtkcompare]
+name = {__name}
+reference = heatequation_ref
+extension = vtu
+
+[formcompiler]
+explicit_time_stepping = 0, 1 | expand scheme
+exact_solution_expression = g
+compare_l2errorsquared = 1e-5
diff --git a/test/heatequation/heatequation_dg_explicit.mini b/test/heatequation/heatequation_dg_explicit.mini
deleted file mode 100644
index 7374c7b64e2e0ac05e7d3720d2483bf39103b64f..0000000000000000000000000000000000000000
--- a/test/heatequation/heatequation_dg_explicit.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = heatequation_dg_explicit
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = heatequation_ref
-extension = vtu
diff --git a/test/heatequation/heatequation_dg_implicit.mini b/test/heatequation/heatequation_dg_implicit.mini
deleted file mode 100644
index 9296d825dcbe56b913013dc322819f9ab92fc95a..0000000000000000000000000000000000000000
--- a/test/heatequation/heatequation_dg_implicit.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = heatequation_dg_implicit
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = heatequation_ref
-extension = vtu
diff --git a/test/heatequation/heatequation_explicit.mini b/test/heatequation/heatequation_explicit.mini
deleted file mode 100644
index 2360fb6bc8436deab3b3cfb68f7146689cbe4d25..0000000000000000000000000000000000000000
--- a/test/heatequation/heatequation_explicit.mini
+++ /dev/null
@@ -1,15 +0,0 @@
-__name = heatequation_explicit
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 8 8
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = heatequation_ref
-extension = vtu
-
-[instat]
-T = 1.0
-dt = 0.01
\ No newline at end of file
diff --git a/test/heatequation/heatequation_implicit.mini b/test/heatequation/heatequation_implicit.mini
deleted file mode 100644
index c49499f7833c2af8acbeca3ac86d3f65097476ec..0000000000000000000000000000000000000000
--- a/test/heatequation/heatequation_implicit.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = heatequation_implicit
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = heatequation_ref
-extension = vtu
diff --git a/test/laplace/CMakeLists.txt b/test/laplace/CMakeLists.txt
index d58b9c54d8757c6b71e2c714e3af23f8ae329135..5ae3a8576c632975f3f33be32aa17be96b6d4597 100644
--- a/test/laplace/CMakeLists.txt
+++ b/test/laplace/CMakeLists.txt
@@ -1,34 +1,10 @@
-add_generated_executable(UFLFILE laplace.ufl
-                         TARGET laplace_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
+dune_add_formcompiler_system_test(UFLFILE laplace.ufl
+                                  BASENAME laplace
+                                  INIFILE laplace.mini)
 
-dune_add_system_test(TARGET laplace_numdiff
-                     INIFILE laplace_numdiff.mini)
-
-
-add_generated_executable(UFLFILE laplace.ufl
-                         TARGET laplace_symdiff
-                         )
-
-dune_add_system_test(TARGET laplace_symdiff
-                     INIFILE laplace_symdiff.mini)
-
-
-add_generated_executable(UFLFILE laplace_dg.ufl
-                         TARGET laplace_dg_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
-
-dune_add_system_test(TARGET laplace_dg_numdiff
-                     INIFILE laplace_dg_numdiff.mini)
-
-add_generated_executable(UFLFILE laplace_dg.ufl
-                         TARGET laplace_dg_symdiff
-                         )
-
-dune_add_system_test(TARGET laplace_dg_symdiff
-                     INIFILE laplace_dg_symdiff.mini)
+dune_add_formcompiler_system_test(UFLFILE laplace_dg.ufl
+                                  BASENAME laplace_dg
+                                  INIFILE laplace_dg.mini)
 
 add_executable(laplace_dg_ref reference_main.cc)
 set_target_properties(laplace_dg_ref PROPERTIES EXCLUDE_FROM_ALL 1)
diff --git a/test/laplace/laplace.mini b/test/laplace/laplace.mini
new file mode 100644
index 0000000000000000000000000000000000000000..1db0ffd82475b75b830f085586bb2d991af2c514
--- /dev/null
+++ b/test/laplace/laplace.mini
@@ -0,0 +1,11 @@
+__name = laplace_{__exec_suffix}
+__exec_suffix = symdiff, numdiff | expand num
+
+lowerleft = 0.0 0.0
+upperright = 1.0 1.0
+elements = 4 4
+elementType = simplical
+printmatrix = true
+
+[formcompiler]
+numerical_jacobian = 0, 1 | expand num
diff --git a/test/laplace/laplace_dg.mini b/test/laplace/laplace_dg.mini
new file mode 100644
index 0000000000000000000000000000000000000000..04a3c3dd0b0c3a5ee4f7d01c073b00f03d498b72
--- /dev/null
+++ b/test/laplace/laplace_dg.mini
@@ -0,0 +1,11 @@
+__name = laplace_dg_{__exec_suffix}
+__exec_suffix = numdiff, symdiff | expand num
+
+lowerleft = 0.0 0.0
+upperright = 1.0 1.0
+elements = 2 2
+elementType = simplical
+printmatrix = true
+
+[formcompiler]
+numerical_jacobian = 1, 0 | expand num
diff --git a/test/laplace/laplace_dg_numdiff.mini b/test/laplace/laplace_dg_numdiff.mini
deleted file mode 100644
index ba1e0014857fc505f0f0f22e6ea8e0b40a1fb095..0000000000000000000000000000000000000000
--- a/test/laplace/laplace_dg_numdiff.mini
+++ /dev/null
@@ -1,7 +0,0 @@
-__name = laplace_dg_numdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 2 2
-elementType = simplical
-printmatrix = true
diff --git a/test/laplace/laplace_dg_symdiff.mini b/test/laplace/laplace_dg_symdiff.mini
deleted file mode 100644
index b03b5ada766d0c520e1afe2ee919a713d80e47ca..0000000000000000000000000000000000000000
--- a/test/laplace/laplace_dg_symdiff.mini
+++ /dev/null
@@ -1,8 +0,0 @@
-__name = laplace_dg_symdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 2 2
-elementType = simplical
-printmatrix = true
-
diff --git a/test/laplace/laplace_numdiff.mini b/test/laplace/laplace_numdiff.mini
deleted file mode 100644
index 8ee48e24d62dc2a16b875a27a02b0bca7b6bba60..0000000000000000000000000000000000000000
--- a/test/laplace/laplace_numdiff.mini
+++ /dev/null
@@ -1,7 +0,0 @@
-__name = laplace_numdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 4 4
-elementType = simplical
-printmatrix = true
diff --git a/test/laplace/laplace_symdiff.mini b/test/laplace/laplace_symdiff.mini
deleted file mode 100644
index c0ee0dd33c0a98aeb36cb68199946593ee752d41..0000000000000000000000000000000000000000
--- a/test/laplace/laplace_symdiff.mini
+++ /dev/null
@@ -1,7 +0,0 @@
-__name = laplace_symdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 4 4
-elementType = simplical
-printmatrix = true
diff --git a/test/nonlinear/CMakeLists.txt b/test/nonlinear/CMakeLists.txt
index cd481d317a73263b0df08383db3e1ab6f6f2dc1d..f5e524fd1aad68633c938bda319ab98ca0939d9e 100644
--- a/test/nonlinear/CMakeLists.txt
+++ b/test/nonlinear/CMakeLists.txt
@@ -1,21 +1,13 @@
-add_generated_executable(UFLFILE nonlinear.ufl
-                         TARGET nonlinear_symdiff
-                         FORM_COMPILER_ARGS
-                         )
-
-dune_add_system_test(TARGET nonlinear_symdiff
-                     INIFILE nonlinear_symdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-add_generated_executable(UFLFILE nonlinear_dg.ufl
-                         TARGET nonlinear_dg
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-1 --compare-l2errorsquared 1e-3
-                         )
-
-dune_add_system_test(TARGET nonlinear_dg
-                     INIFILE nonlinear_dg.mini
-                     )
+dune_add_formcompiler_system_test(UFLFILE nonlinear.ufl
+                                  BASENAME nonlinear
+                                  INIFILE nonlinear.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
+
+dune_add_formcompiler_system_test(UFLFILE nonlinear_dg.ufl
+                                  BASENAME nonlinear_dg
+                                  INIFILE nonlinear_dg.mini
+                                  )
 
 # Add the reference code with the PDELab localoperator that produced
 # the reference vtk file
diff --git a/test/nonlinear/nonlinear_symdiff.mini b/test/nonlinear/nonlinear.mini
similarity index 100%
rename from test/nonlinear/nonlinear_symdiff.mini
rename to test/nonlinear/nonlinear.mini
diff --git a/test/nonlinear/nonlinear_dg.mini b/test/nonlinear/nonlinear_dg.mini
index d2b26e27c4575901a0d094a8da176f2dd13d73d7..d79cf357a82a6bf4c6e402493b4940b299be07cb 100644
--- a/test/nonlinear/nonlinear_dg.mini
+++ b/test/nonlinear/nonlinear_dg.mini
@@ -9,3 +9,8 @@ elementType = simplical
 name = {__name}
 reference = nonlinear_dg
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-1
+compare_l2errorsquared = 1e-3
diff --git a/test/poisson/CMakeLists.txt b/test/poisson/CMakeLists.txt
index 2bc18c5c1e4c0baf87c33f065d79b971b762560b..4455f6ca5f402deebb5ea775a21f4a114f0f94b5 100644
--- a/test/poisson/CMakeLists.txt
+++ b/test/poisson/CMakeLists.txt
@@ -6,141 +6,53 @@ dune_symlink_to_source_files(FILES poisson_ref.vtu
                              )
 
 
-# 1. Poisson Test Case: source f, bc g + numerical differentiation
-add_generated_executable(UFLFILE poisson.ufl
-                         TARGET poisson_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
-
-dune_add_system_test(TARGET poisson_numdiff
-                     INIFILE poisson_numdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-
-# 2. Poisson Test Case: source f, bc g + symbolic differentiation
-add_generated_executable(UFLFILE poisson.ufl
-                         TARGET poisson_symdiff
-                         )
-
-dune_add_system_test(TARGET poisson_symdiff
-                     INIFILE poisson_symdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-# 3. Poisson Test Case: source f, mixed neumann/dirichlet boundary + numerical differentiation
-add_generated_executable(UFLFILE poisson_neumann.ufl
-                         TARGET poisson_neumann_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
-
-dune_add_system_test(TARGET poisson_neumann_numdiff
-                     INIFILE poisson_neumann_numdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-# 4. Poisson Test Case: source f, mixed neumann/dirichlet boundary + symbolic differentiation
-add_generated_executable(UFLFILE poisson_neumann.ufl
-                         TARGET poisson_neumann_symdiff
-                         )
-
-dune_add_system_test(TARGET poisson_neumann_symdiff
-                     INIFILE poisson_neumann_symdiff.mini
-                     )
-
-# 5. Poisson Test Case: DG, f + pure dirichlet, numeric differentiation
-add_generated_executable(UFLFILE poisson_dg.ufl
-                         TARGET poisson_dg_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
-
-dune_add_system_test(TARGET poisson_dg_numdiff
-                     INIFILE poisson_dg_numdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-# 6. Poisson Test Case: DG, f + pure dirichlet, symbolic differentiation
-add_generated_executable(UFLFILE poisson_dg.ufl
-                         TARGET poisson_dg_symdiff
-                         )
-
-dune_add_system_test(TARGET poisson_dg_symdiff
-                     INIFILE poisson_dg_symdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-# 7. Poisson Test Case: DG, mixed bc, numeric differentiation
-add_generated_executable(UFLFILE poisson_dg_neumann.ufl
-                         TARGET poisson_dg_neumann_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
-
-dune_add_system_test(TARGET poisson_dg_neumann_numdiff
-                     INIFILE poisson_dg_neumann_numdiff.mini
-                     )
-
-# 8. Poisson Test Case: DG, mixed bc, symbolic differentiation
-add_generated_executable(UFLFILE poisson_dg_neumann.ufl
-                         TARGET poisson_dg_neumann_symdiff
-                         )
-
-dune_add_system_test(TARGET poisson_dg_neumann_symdiff
-                     INIFILE poisson_dg_neumann_symdiff.mini
-                     )
-
-# 9. Poisson Test Case: matrix free, numeric differentiation
-add_generated_executable(UFLFILE poisson.ufl
-                         TARGET poisson_numdiff_matrix_free
-                         FORM_COMPILER_ARGS --numerical-jacobian --matrix-free
-                         )
-
-dune_add_system_test(TARGET poisson_numdiff_matrix_free
-                     INIFILE poisson_numdiff_matrix_free.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-# 10. Poisson Test Case: matrix free, symbolic differentiation
-add_generated_executable(UFLFILE poisson.ufl
-                         TARGET poisson_symdiff_matrix_free
-                         FORM_COMPILER_ARGS --matrix-free
-                         )
-
-dune_add_system_test(TARGET poisson_symdiff_matrix_free
-                     INIFILE poisson_symdiff_matrix_free.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-# # 11. Poisson Test Case: dg, matrix free, numeric differentiation
-# add_generated_executable(UFLFILE poisson_dg.ufl
-#                          TARGET poisson_dg_numdiff_matrix_free
-#                          FORM_COMPILER_ARGS --numerical-jacobian --matrix-free
-#                          )
-
-# dune_add_system_test(TARGET poisson_dg_numdiff_matrix_free
-#                      INIFILE poisson_dg_numdiff_matrix_free.mini
-#                      SCRIPT dune_vtkcompare.py
-#                      )
-
-# # 12. Poisson Test Case: dg, matrix free, symbolic differentiation
-# add_generated_executable(UFLFILE poisson_dg.ufl
-#                          TARGET poisson_dg_symdiff_matrix_free
-#                          FORM_COMPILER_ARGS --matrix-free
-#                          )
-
-# dune_add_system_test(TARGET poisson_dg_symdiff_matrix_free
-#                      INIFILE poisson_dg_symdiff_matrix_free.mini
-#                      SCRIPT dune_vtkcompare.py
-#                      )
-
-
-# 13. Poisson Test Case: test constant expressions
-add_generated_executable(UFLFILE poisson_cellwise_constant.ufl
-                         TARGET poisson_cellwise_constant
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-l2errorsquared 1e-6
-                         )
-dune_add_system_test(TARGET poisson_cellwise_constant
-                     INIFILE poisson_cellwise_constant.mini
-                     )
+# 1. Poisson Test Case: source f, bc g
+dune_add_formcompiler_system_test(UFLFILE poisson.ufl
+                                  BASENAME poisson
+                                  INIFILE poisson.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
+
+# 2. Poisson Test Case: source f, mixed neumann/dirichlet boundary
+dune_add_formcompiler_system_test(UFLFILE poisson_neumann.ufl
+                                  BASENAME poisson_neumann
+                                  INIFILE poisson_neumann.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
+
+# 3. Poisson Test Case: DG, f + pure dirichlet
+dune_add_formcompiler_system_test(UFLFILE poisson_dg.ufl
+                                  BASENAME poisson_dg
+                                  INIFILE poisson_dg.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
+
+# 4. Poisson Test Case: DG, mixed bc
+dune_add_formcompiler_system_test(UFLFILE poisson_dg_neumann.ufl
+                                  BASENAME poisson_dg_neumann
+                                  INIFILE poisson_dg_neumann.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
+
+# 5. Poisson Test Case: matrix free
+dune_add_formcompiler_system_test(UFLFILE poisson.ufl
+                                  BASENAME poisson_matrix_free
+                                  INIFILE poisson_matrix_free.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
+
+# 6. Poisson Test Case: DG, matrix free
+#dune_add_formcompiler_system_test(UFLFILE poisson_dg.ufl
+#                                  BASENAME poisson_dg_matrix_free
+#                                  INIFILE poisson_dg_matrix_free.mini
+#                                  SCRIPT dune_vtkcompare.py
+#                                  )
+
+# 7. Poisson Test Case: test constant expressions
+dune_add_formcompiler_system_test(UFLFILE poisson_cellwise_constant.ufl
+                                  BASENAME poisson_cellwise_constant
+                                  INIFILE poisson_cellwise_constant.mini
+                                  )
 
 # Add the reference code with the PDELab localoperator that produced
 # the reference vtk file
diff --git a/test/poisson/dimension-grid-variations/CMakeLists.txt b/test/poisson/dimension-grid-variations/CMakeLists.txt
index 9f2229d084feb7e05baa3111ce4b6d4879269a5f..9ef05b56f34f34c1959a0d7f517d5e8dead186fa 100644
--- a/test/poisson/dimension-grid-variations/CMakeLists.txt
+++ b/test/poisson/dimension-grid-variations/CMakeLists.txt
@@ -2,102 +2,60 @@
 # 1D Tests: cg/dg
 #================
 
-add_generated_executable(UFLFILE poisson_1d_cg_interval.ufl
-                         TARGET poisson_1d_cg_interval
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-14 --compare-l2errorsquared 1e-7
-                         )
-
-dune_add_system_test(TARGET poisson_1d_cg_interval
-                     INIFILE poisson_1d_cg_interval.mini
-                     )
-
-add_generated_executable(UFLFILE poisson_1d_dg_interval.ufl
-                         TARGET poisson_1d_dg_interval
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-2 --compare-l2errorsquared 1e-5
-                         )
-
-dune_add_system_test(TARGET poisson_1d_dg_interval
-                     INIFILE poisson_1d_dg_interval.mini
-                     )
+dune_add_formcompiler_system_test(UFLFILE poisson_1d_cg_interval.ufl
+                                  BASENAME poisson_1d_cg_interval
+                                  INIFILE poisson_1d_cg_interval.mini
+                                  )
 
+dune_add_formcompiler_system_test(UFLFILE poisson_1d_dg_interval.ufl
+                                  BASENAME poisson_1d_dg_interval
+                                  INIFILE poisson_1d_dg_interval.mini
+                                  )
 
 #========================================
 # 2D Tests: cg/dg, triangle/quadrilateral
 #========================================
 
-add_generated_executable(UFLFILE poisson_2d_cg_triangle.ufl
-                         TARGET poisson_2d_cg_triangle
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-14 --compare-l2errorsquared 1e-6
-                         )
-
-dune_add_system_test(TARGET poisson_2d_cg_triangle
-                     INIFILE poisson_2d_cg_triangle.mini
-                     )
-
-add_generated_executable(UFLFILE poisson_2d_dg_triangle.ufl
-                         TARGET poisson_2d_dg_triangle
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-1 --compare-l2errorsquared 1e-4
-                         )
-
-dune_add_system_test(TARGET poisson_2d_dg_triangle
-                     INIFILE poisson_2d_dg_triangle.mini
-                     )
-
-add_generated_executable(UFLFILE poisson_2d_cg_quadrilateral.ufl
-                         TARGET poisson_2d_cg_quadrilateral
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-14 --compare-l2errorsquared 1e-6
-                         )
-
-dune_add_system_test(TARGET poisson_2d_cg_quadrilateral
-                     INIFILE poisson_2d_cg_quadrilateral.mini
-                     )
+dune_add_formcompiler_system_test(UFLFILE poisson_2d_cg_triangle.ufl
+                                  BASENAME poisson_2d_cg_triangle
+                                  INIFILE poisson_2d_cg_triangle.mini
+                                  )
 
-add_generated_executable(UFLFILE poisson_2d_dg_quadrilateral.ufl
-                         TARGET poisson_2d_dg_quadrilateral
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-1 --compare-l2errorsquared 1e-4
-                         )
+dune_add_formcompiler_system_test(UFLFILE poisson_2d_dg_triangle.ufl
+                                  BASENAME poisson_2d_dg_triangle
+                                  INIFILE poisson_2d_dg_triangle.mini
+                                  )
 
-dune_add_system_test(TARGET poisson_2d_dg_quadrilateral
-                     INIFILE poisson_2d_dg_quadrilateral.mini
-                     )
+dune_add_formcompiler_system_test(UFLFILE poisson_2d_cg_quadrilateral.ufl
+                                  BASENAME poisson_2d_cg_quadrilateral
+                                  INIFILE poisson_2d_cg_quadrilateral.mini
+                                  )
 
+dune_add_formcompiler_system_test(UFLFILE poisson_2d_dg_quadrilateral.ufl
+                                  BASENAME poisson_2d_dg_quadrilateral
+                                  INIFILE poisson_2d_dg_quadrilateral.mini
+                                  )
 
 #========================================
 # 3D Tests: cg/dg, tetrahedron/hexahedron
 #========================================
 
-add_generated_executable(UFLFILE poisson_3d_cg_tetrahedron.ufl
-                         TARGET poisson_3d_cg_tetrahedron
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-14 --compare-l2errorsquared 1e-4
-                         )
-
-dune_add_system_test(TARGET poisson_3d_cg_tetrahedron
-                     INIFILE poisson_3d_cg_tetrahedron.mini
-                     )
-
-add_generated_executable(UFLFILE poisson_3d_dg_tetrahedron.ufl
-                         TARGET poisson_3d_dg_tetrahedron
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-2 --compare-l2errorsquared 1e-4
-                         )
-
-dune_add_system_test(TARGET poisson_3d_dg_tetrahedron
-                     INIFILE poisson_3d_dg_tetrahedron.mini
-                     )
-
-add_generated_executable(UFLFILE poisson_3d_cg_hexahedron.ufl
-                         TARGET poisson_3d_cg_hexahedron
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1e-14 --compare-l2errorsquared 1e-4
-                         )
-
-dune_add_system_test(TARGET poisson_3d_cg_hexahedron
-                     INIFILE poisson_3d_cg_hexahedron.mini
-                     )
-
-add_generated_executable(UFLFILE poisson_3d_dg_hexahedron.ufl
-                         TARGET poisson_3d_dg_hexahedron
-                         FORM_COMPILER_ARGS --exact-solution-expression g --compare-dofs 1 --compare-l2errorsquared 1e-3
-                         )
-
-dune_add_system_test(TARGET poisson_3d_dg_hexahedron
-                     INIFILE poisson_3d_dg_hexahedron.mini
-                     )
+dune_add_formcompiler_system_test(UFLFILE poisson_3d_cg_tetrahedron.ufl
+                                  BASENAME poisson_3d_cg_tetrahedron
+                                  INIFILE poisson_3d_cg_tetrahedron.mini
+                                  )
+
+dune_add_formcompiler_system_test(UFLFILE poisson_3d_dg_tetrahedron.ufl
+                                  BASENAME poisson_3d_dg_tetrahedron
+                                  INIFILE poisson_3d_dg_tetrahedron.mini
+                                  )
+
+dune_add_formcompiler_system_test(UFLFILE poisson_3d_cg_hexahedron.ufl
+                                  BASENAME poisson_3d_cg_hexahedron
+                                  INIFILE poisson_3d_cg_hexahedron.mini
+                                  )
+
+dune_add_formcompiler_system_test(UFLFILE poisson_3d_dg_hexahedron.ufl
+                                  BASENAME poisson_3d_dg_hexahedron
+                                  INIFILE poisson_3d_dg_hexahedron.mini
+                                  )
diff --git a/test/poisson/dimension-grid-variations/poisson_1d_cg_interval.mini b/test/poisson/dimension-grid-variations/poisson_1d_cg_interval.mini
index 016ce0b61111528827273e7cfcd3c73e68042660..a3680f2cfc0181c7dfe127dc13db166058ad27b2 100644
--- a/test/poisson/dimension-grid-variations/poisson_1d_cg_interval.mini
+++ b/test/poisson/dimension-grid-variations/poisson_1d_cg_interval.mini
@@ -6,3 +6,8 @@ extension = 1.
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-14
+compare_l2errorsquared = 1e-7
diff --git a/test/poisson/dimension-grid-variations/poisson_1d_dg_interval.mini b/test/poisson/dimension-grid-variations/poisson_1d_dg_interval.mini
index f053c7321cb76e5854498a60dbbf253facca52cc..c1f1e96af77686146a3ad65ffdec145ebafa81a9 100644
--- a/test/poisson/dimension-grid-variations/poisson_1d_dg_interval.mini
+++ b/test/poisson/dimension-grid-variations/poisson_1d_dg_interval.mini
@@ -6,3 +6,8 @@ extension = 1.
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-2
+compare_l2errorsquared = 1e-5
diff --git a/test/poisson/dimension-grid-variations/poisson_2d_cg_quadrilateral.mini b/test/poisson/dimension-grid-variations/poisson_2d_cg_quadrilateral.mini
index d0ede6942e2f529eab9ba799de1376621e1917a7..8f5e193a613a7caeb1a9fc2796e9d88b0f5c9b22 100644
--- a/test/poisson/dimension-grid-variations/poisson_2d_cg_quadrilateral.mini
+++ b/test/poisson/dimension-grid-variations/poisson_2d_cg_quadrilateral.mini
@@ -6,3 +6,8 @@ extension = 1. 1.
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-14
+compare_l2errorsquared = 1e-6
diff --git a/test/poisson/dimension-grid-variations/poisson_2d_cg_triangle.mini b/test/poisson/dimension-grid-variations/poisson_2d_cg_triangle.mini
index bf7adf0a3d966c4239e5d6861b3ea4187efa4f53..3ba7459606e0a82c13861b9a1ea075c073475135 100644
--- a/test/poisson/dimension-grid-variations/poisson_2d_cg_triangle.mini
+++ b/test/poisson/dimension-grid-variations/poisson_2d_cg_triangle.mini
@@ -8,3 +8,8 @@ elementType = simplical
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-14
+compare_l2errorsquared = 1e-6
diff --git a/test/poisson/dimension-grid-variations/poisson_2d_dg_quadrilateral.mini b/test/poisson/dimension-grid-variations/poisson_2d_dg_quadrilateral.mini
index 4bea68343fc24ebeee0b4188d6b17004f086c47d..ca35eccb50884552251748d611cf85fc647c55e3 100644
--- a/test/poisson/dimension-grid-variations/poisson_2d_dg_quadrilateral.mini
+++ b/test/poisson/dimension-grid-variations/poisson_2d_dg_quadrilateral.mini
@@ -6,3 +6,8 @@ extension = 1. 1.
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-1
+compare_l2errorsquared = 1e-4
diff --git a/test/poisson/dimension-grid-variations/poisson_2d_dg_triangle.mini b/test/poisson/dimension-grid-variations/poisson_2d_dg_triangle.mini
index dedd6a3ffac42315ea150ad28849c50008fbe1ec..94fcda9c93fcdc88e6ed3ffede2cba8f3c07e9a4 100644
--- a/test/poisson/dimension-grid-variations/poisson_2d_dg_triangle.mini
+++ b/test/poisson/dimension-grid-variations/poisson_2d_dg_triangle.mini
@@ -8,3 +8,8 @@ elementType = simplical
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-1
+compare_l2errorsquared = 1e-4
diff --git a/test/poisson/dimension-grid-variations/poisson_3d_cg_hexahedron.mini b/test/poisson/dimension-grid-variations/poisson_3d_cg_hexahedron.mini
index ee7893caae615184a6e8cca678f0e600f21bfdaa..ca47f1c9471e75a4fcdb8a90d9efe9e27ed1568a 100644
--- a/test/poisson/dimension-grid-variations/poisson_3d_cg_hexahedron.mini
+++ b/test/poisson/dimension-grid-variations/poisson_3d_cg_hexahedron.mini
@@ -6,3 +6,8 @@ extension = 1. 1. 1.
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-14
+compare_l2errorsquared = 1e-4
diff --git a/test/poisson/dimension-grid-variations/poisson_3d_cg_tetrahedron.mini b/test/poisson/dimension-grid-variations/poisson_3d_cg_tetrahedron.mini
index 6a788f16f67aba18d73c390b00cb5af8dbcb5ad3..178cd983398e277fa30948937273de91342bfd85 100644
--- a/test/poisson/dimension-grid-variations/poisson_3d_cg_tetrahedron.mini
+++ b/test/poisson/dimension-grid-variations/poisson_3d_cg_tetrahedron.mini
@@ -8,3 +8,8 @@ elementType = simplical
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-14
+compare_l2errorsquared = 1e-4
diff --git a/test/poisson/dimension-grid-variations/poisson_3d_dg_hexahedron.mini b/test/poisson/dimension-grid-variations/poisson_3d_dg_hexahedron.mini
index 82c8faec2c8b8d23f15d09cbaa56abcf7eb385b5..4c195f8efe9b4d8b82bd3a597994e5e4e769a006 100644
--- a/test/poisson/dimension-grid-variations/poisson_3d_dg_hexahedron.mini
+++ b/test/poisson/dimension-grid-variations/poisson_3d_dg_hexahedron.mini
@@ -6,3 +6,8 @@ extension = 1. 1. 1.
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1
+compare_l2errorsquared = 1e-3
diff --git a/test/poisson/dimension-grid-variations/poisson_3d_dg_tetrahedron.mini b/test/poisson/dimension-grid-variations/poisson_3d_dg_tetrahedron.mini
index 16f1adaffaebb6ab4af342789a6c617ed73a9d8b..0d497ae5ab49bd88dbc02c7890b61d2ba3aff06f 100644
--- a/test/poisson/dimension-grid-variations/poisson_3d_dg_tetrahedron.mini
+++ b/test/poisson/dimension-grid-variations/poisson_3d_dg_tetrahedron.mini
@@ -8,3 +8,8 @@ elementType = simplical
 [wrapper.vtkcompare]
 name = {__name}
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_dofs = 1e-2
+compare_l2errorsquared = 1e-4
diff --git a/test/poisson/poisson_neumann_numdiff.mini b/test/poisson/poisson.mini
similarity index 54%
rename from test/poisson/poisson_neumann_numdiff.mini
rename to test/poisson/poisson.mini
index 5c779a14edfb5059c96fe23a8095159840d57191..eb8c175b6a9b09da89b11ee244978c4099ede35e 100644
--- a/test/poisson/poisson_neumann_numdiff.mini
+++ b/test/poisson/poisson.mini
@@ -1,4 +1,5 @@
-__name = poisson_neumann_numdiff
+__name = poisson_{__exec_suffix}
+__exec_suffix = numdiff, symdiff | expand num
 
 lowerleft = 0.0 0.0
 upperright = 1.0 1.0
@@ -9,3 +10,6 @@ elementType = simplical
 name = {__name}
 reference = poisson_ref
 extension = vtu
+
+[formcompiler]
+numerical_jacobian = 1, 0 | expand num
diff --git a/test/poisson/poisson_cellwise_constant.mini b/test/poisson/poisson_cellwise_constant.mini
index 5b1ceb7dbd66eab1366e0cf89dda846e9d269fac..86827ea49f11ff5287cf0f37206caa621d44caf7 100644
--- a/test/poisson/poisson_cellwise_constant.mini
+++ b/test/poisson/poisson_cellwise_constant.mini
@@ -9,3 +9,7 @@ elementType = simplical
 name = {__name}
 reference = poisson_ref
 extension = vtu
+
+[formcompiler]
+exact_solution_expression = g
+compare_l2errorsquared = 1e-6
diff --git a/test/poisson/poisson_dg_neumann_symdiff.mini b/test/poisson/poisson_dg.mini
similarity index 54%
rename from test/poisson/poisson_dg_neumann_symdiff.mini
rename to test/poisson/poisson_dg.mini
index 4dd175ddaf549e3e20435ac2ed7fb0bde88ea811..fb3c992b799a53f21043498ed249ab880315ef78 100644
--- a/test/poisson/poisson_dg_neumann_symdiff.mini
+++ b/test/poisson/poisson_dg.mini
@@ -1,4 +1,5 @@
-__name = poisson_dg_neumann_symdiff
+__name = poisson_dg_{__exec_suffix}
+__exec_suffix = numdiff, symdiff | expand num
 
 lowerleft = 0.0 0.0
 upperright = 1.0 1.0
@@ -9,3 +10,6 @@ elementType = simplical
 name = {__name}
 reference = poisson_dg_ref
 extension = vtu
+
+[formcompiler]
+numerical_jacobian = 1, 0 | expand num
diff --git a/test/poisson/poisson_dg_matrix_free.mini b/test/poisson/poisson_dg_matrix_free.mini
new file mode 100644
index 0000000000000000000000000000000000000000..e07d58b9d1103ba171b2bcb4f0a0c6b6a5bb4ddb
--- /dev/null
+++ b/test/poisson/poisson_dg_matrix_free.mini
@@ -0,0 +1,16 @@
+__name = poisson_dg_matrix_free_{__exec_suffix}
+__exec_suffix = numdiff, symdiff | expand num
+
+lowerleft = 0.0 0.0
+upperright = 1.0 1.0
+elements = 32 32
+elementType = simplical
+
+[wrapper.vtkcompare]
+name = {__name}
+reference = poisson_dg_ref
+extension = vtu
+
+[formcompiler]
+numerical_jacobian = 1, 0 | expand num
+matrix_free = 1
diff --git a/test/poisson/poisson_dg_numdiff.mini b/test/poisson/poisson_dg_neumann.mini
similarity index 53%
rename from test/poisson/poisson_dg_numdiff.mini
rename to test/poisson/poisson_dg_neumann.mini
index 146955e8a8d3699cfcb0e7a145a1619a1c49ab60..41a09182baaffb10e0000c2a8ecaea094d4f943c 100644
--- a/test/poisson/poisson_dg_numdiff.mini
+++ b/test/poisson/poisson_dg_neumann.mini
@@ -1,4 +1,5 @@
-__name = poisson_dg_numdiff
+__name = poisson_dg_neumann_{__exec_suffix}
+__exec_suffix = numdiff, symdiff | expand num
 
 lowerleft = 0.0 0.0
 upperright = 1.0 1.0
@@ -9,3 +10,6 @@ elementType = simplical
 name = {__name}
 reference = poisson_dg_ref
 extension = vtu
+
+[formcompiler]
+numerical_jacobian = 1, 0 | expand num
diff --git a/test/poisson/poisson_dg_neumann_numdiff.mini b/test/poisson/poisson_dg_neumann_numdiff.mini
deleted file mode 100644
index b0847a74943f945e73d011fc265ae306584e89cb..0000000000000000000000000000000000000000
--- a/test/poisson/poisson_dg_neumann_numdiff.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = poisson_dg_neumann_numdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = poisson_dg_ref
-extension = vtu
diff --git a/test/poisson/poisson_dg_numdiff_matrix_free.mini b/test/poisson/poisson_dg_numdiff_matrix_free.mini
deleted file mode 100644
index b45d4a8654e11107f8bbf111db0f996461085e2a..0000000000000000000000000000000000000000
--- a/test/poisson/poisson_dg_numdiff_matrix_free.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = poisson_dg_numdiff_matrix_free
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = poisson_dg_ref
-extension = vtu
diff --git a/test/poisson/poisson_dg_symdiff.mini b/test/poisson/poisson_dg_symdiff.mini
deleted file mode 100644
index fe696b111fba1c0f78ec8ffc3f2ff4e8143ff3f2..0000000000000000000000000000000000000000
--- a/test/poisson/poisson_dg_symdiff.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = poisson_dg_symdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = poisson_dg_ref
-extension = vtu
diff --git a/test/poisson/poisson_dg_symdiff_matrix_free.mini b/test/poisson/poisson_dg_symdiff_matrix_free.mini
deleted file mode 100644
index c3fcaf7fcf1576850a8d1a99f4a1d8b07d0ddcd8..0000000000000000000000000000000000000000
--- a/test/poisson/poisson_dg_symdiff_matrix_free.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = poisson_dg_symdiff_matrix_free
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = poisson_dg_ref
-extension = vtu
diff --git a/test/poisson/poisson_matrix_free.mini b/test/poisson/poisson_matrix_free.mini
new file mode 100644
index 0000000000000000000000000000000000000000..6e58960a0e2e80cc862923aa061cb93eaf600a4d
--- /dev/null
+++ b/test/poisson/poisson_matrix_free.mini
@@ -0,0 +1,16 @@
+__name = poisson_matrix_free_{__exec_suffix}
+__exec_suffix = numdiff, symdiff | expand num
+
+lowerleft = 0.0 0.0
+upperright = 1.0 1.0
+elements = 32 32
+elementType = simplical
+
+[wrapper.vtkcompare]
+name = {__name}
+reference = poisson_ref
+extension = vtu
+
+[formcompiler]
+numerical_jacobian = 1, 0 | expand num
+matrix_free = 1
diff --git a/test/poisson/poisson_neumann_symdiff.mini b/test/poisson/poisson_neumann.mini
similarity index 53%
rename from test/poisson/poisson_neumann_symdiff.mini
rename to test/poisson/poisson_neumann.mini
index 8e2c2fb03673468f9f5fcdf67ab509ef339bfdfe..d5cb21ff2d0806e27f326d35bebc40957f823742 100644
--- a/test/poisson/poisson_neumann_symdiff.mini
+++ b/test/poisson/poisson_neumann.mini
@@ -1,4 +1,5 @@
-__name = poisson_neumann_symdiff
+__name = poisson_neumann_{__exec_suffix}
+__exec_suffix = numdiff, symdiff | expand num
 
 lowerleft = 0.0 0.0
 upperright = 1.0 1.0
@@ -9,3 +10,6 @@ elementType = simplical
 name = {__name}
 reference = poisson_ref
 extension = vtu
+
+[formcompiler]
+numerical_jacobian = 1, 0 | expand num
diff --git a/test/poisson/poisson_numdiff.mini b/test/poisson/poisson_numdiff.mini
deleted file mode 100644
index 6d4507180f6f46f026231e4fc4bb3f7f8eb0ca6f..0000000000000000000000000000000000000000
--- a/test/poisson/poisson_numdiff.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = poisson_numdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = poisson_ref
-extension = vtu
diff --git a/test/poisson/poisson_numdiff_matrix_free.mini b/test/poisson/poisson_numdiff_matrix_free.mini
deleted file mode 100644
index 4662d83881c20c13ffe49055338e1fc775020ab3..0000000000000000000000000000000000000000
--- a/test/poisson/poisson_numdiff_matrix_free.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = poisson_numdiff_matrix_free
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = poisson_ref
-extension = vtu
diff --git a/test/poisson/poisson_symdiff.mini b/test/poisson/poisson_symdiff.mini
deleted file mode 100644
index e3fa2f3fb8508f2204f4547e1c9ba33c8c2d2fe0..0000000000000000000000000000000000000000
--- a/test/poisson/poisson_symdiff.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = poisson_symdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = poisson_ref
-extension = vtu
diff --git a/test/poisson/poisson_symdiff_matrix_free.mini b/test/poisson/poisson_symdiff_matrix_free.mini
deleted file mode 100644
index 8d288ef3358fdda09706b80874e444d0ff5c8b2c..0000000000000000000000000000000000000000
--- a/test/poisson/poisson_symdiff_matrix_free.mini
+++ /dev/null
@@ -1,11 +0,0 @@
-__name = poisson_symdiff_matrix_free
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 32 32
-elementType = simplical
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = poisson_ref
-extension = vtu
diff --git a/test/stokes/CMakeLists.txt b/test/stokes/CMakeLists.txt
index 57cf3d0196269a190c1c6282cc57c9153e8670e2..8d6fa96d619fc308cba1a75296dc91c84fe43413 100644
--- a/test/stokes/CMakeLists.txt
+++ b/test/stokes/CMakeLists.txt
@@ -2,59 +2,20 @@ dune_symlink_to_source_files(FILES hagenpoiseuille_ref.vtu
                                    hagenpoiseuille_dg_ref.vtu
                              )
 
-add_generated_executable(UFLFILE stokes.ufl
-                         TARGET stokes_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
-
-dune_add_system_test(TARGET stokes_numdiff
-                     INIFILE stokes_numdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-add_generated_executable(UFLFILE stokes.ufl
-                         TARGET stokes_symdiff
-                         )
-
-dune_add_system_test(TARGET stokes_symdiff
-                     INIFILE stokes_symdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-add_generated_executable(UFLFILE stokes_dg.ufl
-                         TARGET stokes_dg_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
-
-dune_add_system_test(TARGET stokes_dg_numdiff
-                     INIFILE stokes_dg_numdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-add_generated_executable(UFLFILE stokes_dg.ufl
-                         TARGET stokes_dg_symdiff
-                         )
-
-dune_add_system_test(TARGET stokes_dg_symdiff
-                     INIFILE stokes_dg_symdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-add_generated_executable(UFLFILE stokes_stress.ufl
-                         TARGET stokes_stress_numdiff
-                         FORM_COMPILER_ARGS --numerical-jacobian
-                         )
-
-dune_add_system_test(TARGET stokes_stress_numdiff
-                     INIFILE stokes_stress_numdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
-
-add_generated_executable(UFLFILE stokes_stress.ufl
-                         TARGET stokes_stress_symdiff
-                         )
-
-dune_add_system_test(TARGET stokes_stress_symdiff
-                     INIFILE stokes_stress_symdiff.mini
-                     SCRIPT dune_vtkcompare.py
-                     )
+dune_add_formcompiler_system_test(UFLFILE stokes.ufl
+                                  BASENAME stokes
+                                  INIFILE stokes.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
+
+dune_add_formcompiler_system_test(UFLFILE stokes_dg.ufl
+                                  BASENAME stokes_dg
+                                  INIFILE stokes_dg.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
+
+dune_add_formcompiler_system_test(UFLFILE stokes_stress.ufl
+                                  BASENAME stokes_stress
+                                  INIFILE stokes_stress.mini
+                                  SCRIPT dune_vtkcompare.py
+                                  )
diff --git a/test/stokes/stokes_stress_symdiff.mini b/test/stokes/stokes.mini
similarity index 58%
rename from test/stokes/stokes_stress_symdiff.mini
rename to test/stokes/stokes.mini
index 5fdeccefb5e7277c30c28bc2587acebea0e564dc..23a7932929a7783a92ee032727b9749022bdfe47 100644
--- a/test/stokes/stokes_stress_symdiff.mini
+++ b/test/stokes/stokes.mini
@@ -1,4 +1,5 @@
-__name = stokes_stress_symdiff
+__name = stokes_{__exec_suffix}
+__exec_suffix = symdiff, numdiff | expand num
 
 lowerleft = 0.0 0.0
 upperright = 1.0 1.0
@@ -10,3 +11,6 @@ printmatrix = false
 name = {__name}
 reference = hagenpoiseuille_ref
 extension = vtu
+
+[formcompiler]
+numerical_jacobian = 0, 1 | expand num
diff --git a/test/stokes/stokes_dg_numdiff.mini b/test/stokes/stokes_dg.mini
similarity index 64%
rename from test/stokes/stokes_dg_numdiff.mini
rename to test/stokes/stokes_dg.mini
index 9b6a05f163be417c0983c7e9f0c42607abf34f0f..6448f4f5b36dfad891d76e069c3e5573546e6f85 100644
--- a/test/stokes/stokes_dg_numdiff.mini
+++ b/test/stokes/stokes_dg.mini
@@ -1,4 +1,5 @@
-__name = stokes_dg_numdiff
+__name = stokes_dg_{__exec_suffix}
+__exec_suffix = symdiff, numdiff | expand num
 
 lowerleft = 0.0 0.0
 upperright = 1.0 1.0
@@ -12,3 +13,6 @@ reference = hagenpoiseuille_dg_ref
 extension = vtu
 zeroThreshold.data_0 = 1e-6
 zeroThreshold.data_1 = 1e-6
+
+[formcompiler]
+numerical_jacobian = 0, 1 | expand num
diff --git a/test/stokes/stokes_dg_symdiff.mini b/test/stokes/stokes_dg_symdiff.mini
deleted file mode 100644
index 42767d55143d6fce285de4ae0edf79d2d54aa4ab..0000000000000000000000000000000000000000
--- a/test/stokes/stokes_dg_symdiff.mini
+++ /dev/null
@@ -1,12 +0,0 @@
-__name = stokes_dg_symdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 16 16
-elementType = simplical
-printmatrix = false
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = hagenpoiseuille_dg_ref
-extension = vtu
diff --git a/test/stokes/stokes_numdiff.mini b/test/stokes/stokes_numdiff.mini
deleted file mode 100644
index 0f52d1358312990c81b151fb4e39fc295927f2ec..0000000000000000000000000000000000000000
--- a/test/stokes/stokes_numdiff.mini
+++ /dev/null
@@ -1,12 +0,0 @@
-__name = stokes_numdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 16 16
-elementType = simplical
-printmatrix = false
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = hagenpoiseuille_ref
-extension = vtu
diff --git a/test/stokes/stokes_symdiff.mini b/test/stokes/stokes_stress.mini
similarity index 57%
rename from test/stokes/stokes_symdiff.mini
rename to test/stokes/stokes_stress.mini
index c5b554e8654d38f2e612360d21070d7ca8271096..642ef6d2ea8768f1fad13f29c6773e2ee173b830 100644
--- a/test/stokes/stokes_symdiff.mini
+++ b/test/stokes/stokes_stress.mini
@@ -1,4 +1,5 @@
-__name = stokes_symdiff
+__name = stokes_stress_{__exec_suffix}
+__exec_suffix = symdiff, numdiff | expand num
 
 lowerleft = 0.0 0.0
 upperright = 1.0 1.0
@@ -7,7 +8,9 @@ elementType = simplical
 printmatrix = false
 
 [wrapper.vtkcompare]
-zeroThreshold.data_0 = 1e-7
 name = {__name}
 reference = hagenpoiseuille_ref
 extension = vtu
+
+[formcompiler]
+numerical_jacobian = 0, 1 | expand num
diff --git a/test/stokes/stokes_stress_numdiff.mini b/test/stokes/stokes_stress_numdiff.mini
deleted file mode 100644
index 06431fc30ddeef49c2a9c6c075f266b9d57805bf..0000000000000000000000000000000000000000
--- a/test/stokes/stokes_stress_numdiff.mini
+++ /dev/null
@@ -1,12 +0,0 @@
-__name = stokes_stress_numdiff
-
-lowerleft = 0.0 0.0
-upperright = 1.0 1.0
-elements = 16 16
-elementType = simplical
-printmatrix = false
-
-[wrapper.vtkcompare]
-name = {__name}
-reference = hagenpoiseuille_ref
-extension = vtu