diff -u b/core/includes/common.inc b/core/includes/common.inc
--- b/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -4718,7 +4718,6 @@
     $elements['#children'] = $elements['#markup'] . $elements['#children'];
   }
 
-
   // Add any JavaScript state information associated with the element.
   if (!empty($elements['#states'])) {
     drupal_process_states($elements);
diff -u b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
--- b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Common/RenderTest.php
@@ -72,14 +72,78 @@
         ),
         'expected' => '',
       ),
+
+      // Test handling of #markup as a fallback for #theme hooks.
+      // Simple #markup with no theme.
       array(
-        'name' => 'basic renderable array',
+        'name' => 'basic #markup based renderable array',
         'value' => array('#markup' => 'foo'),
         'expected' => 'foo',
       ),
+      // Theme suggestion is not implemented, #markup should be rendered.
+      array(
+        'name' => '#markup fallback for #theme suggestion not implemented',
+        'value' => array(
+          '#theme' => array('suggestionnotimplemented'),
+          '#markup' => 'foo',
+        ),
+        'expected' => 'foo',
+      ),
+      // Theme suggestion is not implemented, child #markup should be rendered.
+      array(
+        'name' => '#markup fallback for child elements, #theme suggestion not implemented',
+        'value' => array(
+          '#theme' => array('suggestionnotimplemented'),
+          'child' => array(
+            '#markup' => 'foo',
+          ),
+        ),
+        'expected' => 'foo',
+      ),
+      // Theme suggestion is implemented but returns empty string, #markup
+      // should not be rendered.
+      array(
+        'name' => 'Avoid #markup if #theme is implemented but returns an empty string',
+        'value' => array(
+          '#theme' => array('common_test_empty'),
+          '#markup' => 'foo',
+        ),
+        'expected' => '',
+      ),
+      // Theme suggestion is implemented but returns empty string, children
+      // should not be rendered.
+      array(
+        'name' => 'Avoid rendering child elements if #theme is implemented but returns an empty string',
+        'value' => array(
+          '#theme' => array('common_test_empty'),
+          'child' => array(
+            '#markup' => 'foo',
+          ),
+        ),
+        'expected' => '',
+      ),
+
       // Test handling of #children and child renderable elements.
-      // #theme is not set, #children will be assumed to be the rendered
-      // child elements even though the #markup for 'child' differs.
+      // #theme is not set, #children is not set and the array has children.
+      array(
+        'name' => '#theme is not set, #children is not set and array has children',
+        'value' => array(
+          'child' => array('#markup' => 'bar'),
+        ),
+        'expected' => 'bar',
+      ),
+      // #theme is not set, #children is set but empty and the array has
+      // children.
+      array(
+        'name' => '#theme is not set, #children is an empty string and array has children',
+        'value' => array(
+          '#children' => '',
+          'child' => array('#markup' => 'bar'),
+        ),
+        'expected' => 'bar',
+      ),
+      // #theme is not set, #children is not empty and will be assumed to be the
+      // rendered child elements even though the #markup for 'child' differs.
       array(
         'name' => '#theme is not set, #children is set and array has children',
         'value' => array(
@@ -101,6 +165,21 @@
         'expected' => 'foobar',
       ),
       // #theme is implemented but #render_children is TRUE. As in the case
+      // where #theme is not set, empty #children means child elements are
+      // rendered recursively.
+      array(
+        'name' => '#theme is implemented, #render_children is TRUE, #children is empty and array has children',
+        'value' => array(
+          '#theme' => 'common_test_foo',
+          '#children' => '',
+          '#render_children' => TRUE,
+          'child' => array(
+            '#markup' => 'boo',
+          ),
+        ),
+        'expected' => 'boo',
+      ),
+      // #theme is implemented but #render_children is TRUE. As in the case
       // where #theme is not set, #children will take precedence over 'child'.
       array(
         'name' => '#theme is implemented, #render_children is TRUE, #children is set and array has children',
@@ -115,65 +194,13 @@
         'expected' => 'baz',
       ),
     );
+
     foreach($types as $type) {
       $this->assertIdentical(drupal_render($type['value']), $type['expected'], '"' . $type['name'] . '" input rendered correctly by drupal_render().');
     }
   }
 
   /**
-   * Tests fallback rendering behaviour when #theme is not implemented.
-   *
-   * If #theme is set and is an implemented theme hook then theme() is 100%
-   * responsible for rendering the array including children and #markup.
-   *
-   * If #theme is not set or is not found in the registry then drupal_render()
-   * should recursively render child attributes of the array and #markup.
-   *
-   * This dual rendering behaviour is only relevant to the internal processing
-   * of drupal_render() before #theme_wrappers are called, so not #prefix and
-   * #suffix for example.
-   */
-  function testDrupalRenderFallbackRender() {
-    // Theme suggestion is not implemented, #markup should be rendered.
-    $theme_suggestion_not_implemented_has_markup = array(
-      '#theme' => array('suggestionnotimplemented'),
-      '#markup' => 'foo',
-    );
-    $rendered = drupal_render($theme_suggestion_not_implemented_has_markup);
-    $this->assertIdentical($rendered, 'foo');
-
-    // Theme suggestion is not implemented, children should be rendered.
-    $theme_suggestion_not_implemented_has_children = array(
-      '#theme' => array('suggestionnotimplemented'),
-      'child' => array(
-        '#markup' => 'foo',
-      ),
-    );
-    $rendered = drupal_render($theme_suggestion_not_implemented_has_children);
-    $this->assertIdentical($rendered, 'foo');
-
-    // Theme suggestion is implemented but returns empty string, #markup should
-    // not be rendered.
-    $theme_implemented_is_empty_has_markup = array(
-      '#theme' => array('common_test_empty'),
-      '#markup' => 'foo',
-    );
-    $rendered = drupal_render($theme_implemented_is_empty_has_markup);
-    $this->assertIdentical($rendered, '');
-
-    // Theme suggestion is implemented but returns empty string, children should
-    // not be rendered.
-    $theme_implemented_is_empty_has_children = array(
-      '#theme' => array('common_test_empty'),
-      'child' => array(
-        '#markup' => 'foo',
-      ),
-    );
-    $rendered = drupal_render($theme_implemented_is_empty_has_children);
-    $this->assertIdentical($rendered, '');
-  }
-
-  /**
    * Tests sorting by weight.
    */
   function testDrupalRenderSorting() {
