coveralls: 
[![Coverage Status](https://coveralls.io/builds/14177954/badge)](https://coveralls.io/builds/14177954)

Coverage increased (+0.003%) to 87.456% when pulling **9dbc760a4ebbee8a5e5c5201446966b012b5d80d on artragis:fix_327** into **862b130652b9118eb8d5681923c04edb000245d3 on nose-devs:master**.

coveralls: 
[![Coverage Status](https://coveralls.io/builds/14177954/badge)](https://coveralls.io/builds/14177954)

Coverage increased (+0.003%) to 87.456% when pulling **9dbc760a4ebbee8a5e5c5201446966b012b5d80d on artragis:fix_327** into **862b130652b9118eb8d5681923c04edb000245d3 on nose-devs:master**.

katrinabrock: Did adding a docstring to the test actually cause it to fail? If not, please write a test that fails in mainline to demonstrate the issue.
artragis: > Did adding a docstring to the test actually cause it  to fail? If not, please write a test that fails in mainline to  demonstrate the issue.

Yes it did. That's why I had to change the "expected" text 


diff --git a/nose2/plugins/layers.py b/nose2/plugins/layers.py
index 43025ca..eda14dc 100644
--- a/nose2/plugins/layers.py
+++ b/nose2/plugins/layers.py
@@ -235,6 +235,9 @@ class LayerReporter(events.Plugin):
         if event.errorList and hasattr(event.test, 'layer'):
             # walk back layers to build full description
             self.describeLayers(event)
+        # we need to remove "\n" from description to keep a well indented report when tests have docstrings
+        # see https://github.com/nose-devs/nose2/issues/327 for more information
+        event.description = event.description.replace('\n', ' ')
 
     def describeLayers(self, event):
         desc = [event.description]

Layer-reporter does not indent docstring 
Given a test
def test_mymethond(self):
    """what this does

   hi there
   """

nose2 will output 'what this does' when the test is run, but the text will not be indented to reflect the layers used. 

Result of test run: 
TopLayer
&nbsp;&nbsp;SecondLayer
&nbsp;&nbsp;&nbsp;&nbsp;test_find_unassigned_signals (test_wrapper.SecondLayerTests) ... ok
&nbsp;&nbsp;&nbsp;&nbsp;test_no_newer_definitions (test_wrapper.SecondLayerTests)
Test that versions in API Wrapper are the latest ... ok
&nbsp;&nbsp;&nbsp;&nbsp;test_only_add_customer_once (test_wrapper.SecondLayerTests) ... ok
&nbsp;&nbsp;&nbsp;&nbsp;test_only_one_parquet_file_pr_customer (test_wrapper.SecondLayerTests) ... ok

Expected:
TopLayer
&nbsp;&nbsp;SecondLayer
&nbsp;&nbsp;&nbsp;&nbsp;test_find_unassigned_signals (test_wrapper.SecondLayerTests) ... ok
&nbsp;&nbsp;&nbsp;&nbsp;test_no_newer_definitions (test_wrapper.SecondLayerTests)
&nbsp;&nbsp;&nbsp;&nbsp;Test that versions in API Wrapper are the latest ... ok
&nbsp;&nbsp;&nbsp;&nbsp;test_only_add_customer_once (test_wrapper.SecondLayerTests) ... ok
&nbsp;&nbsp;&nbsp;&nbsp;test_only_one_parquet_file_pr_customer (test_wrapper.SecondLayerTests) ... ok

or maybe even
TopLayer
&nbsp;&nbsp;SecondLayer
&nbsp;&nbsp;&nbsp;&nbsp;test_find_unassigned_signals (test_wrapper.SecondLayerTests) ... ok
&nbsp;&nbsp;&nbsp;&nbsp;Test that versions in API Wrapper are the latest (test_wrapper.SecondLayerTests) ... ok
&nbsp;&nbsp;&nbsp;&nbsp;test_only_add_customer_once (test_wrapper.SecondLayerTests) ... ok
&nbsp;&nbsp;&nbsp;&nbsp;test_only_one_parquet_file_pr_customer (test_wrapper.SecondLayerTests) ... ok
diff --git a/nose2/tests/functional/support/scenario/layers/test_layers.py b/nose2/tests/functional/support/scenario/layers/test_layers.py
index e800780..a35bb0f 100644
--- a/nose2/tests/functional/support/scenario/layers/test_layers.py
+++ b/nose2/tests/functional/support/scenario/layers/test_layers.py
@@ -180,6 +180,8 @@ class InnerD(unittest.TestCase):
     layer = LayerD
 
     def test(self):
+        """test with docstring
+        """
         self.assertEqual(
             {'base': 'setup',
              'layerD': 'setup'},
diff --git a/nose2/tests/functional/test_layers_plugin.py b/nose2/tests/functional/test_layers_plugin.py
index 9666dba..c658bbe 100644
--- a/nose2/tests/functional/test_layers_plugin.py
+++ b/nose2/tests/functional/test_layers_plugin.py
@@ -56,7 +56,7 @@ class TestLayers(FunctionalTestCase):
 Base
   test \(test_layers.Outer\) ... ok
   LayerD
-    test \(test_layers.InnerD\) ... ok
+    test \(test_layers.InnerD\) test with docstring ... ok
   LayerA
     test \(test_layers.InnerA\) ... ok
   LayerB

pip install -e .[coverage_plugin,doc]
parse_log_pytest
requirements.txt
pytest
apt-get update apt-get install -y gcc
3.5
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.13
attrs==22.2.0
Babel==2.11.0
certifi==2021.5.30
charset-normalizer==2.0.12
coverage==6.2
docutils==0.18.1
idna==3.10
imagesize==1.4.1
importlib-metadata==4.8.3
iniconfig==1.1.1
Jinja2==3.0.3
MarkupSafe==2.0.1
mock==5.2.0
-e git+https://github.com/nose-devs/nose2.git@862b130652b9118eb8d5681923c04edb000245d3#egg=nose2
packaging==21.3
pluggy==1.0.0
py==1.11.0
Pygments==2.14.0
pyparsing==3.1.4
pytest==7.0.1
pytz==2025.2
requests==2.27.1
six==1.17.0
snowballstemmer==2.2.0
Sphinx==5.3.0
sphinx-rtd-theme==2.0.0
sphinxcontrib-applehelp==1.0.2
sphinxcontrib-devhelp==1.0.2
sphinxcontrib-htmlhelp==2.0.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==1.0.3
sphinxcontrib-serializinghtml==1.1.5
tomli==1.2.3
typing_extensions==4.1.1
urllib3==1.26.20
zipp==3.6.0

name: nose2
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2021.5.30=py36h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.3=he6710b0_2
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=21.2.2=py36h06a4308_0
  - python=3.6.13=h12debd9_1
  - readline=8.2=h5eee18b_0
  - setuptools=58.0.4=py36h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.37.1=pyhd3eb1b0_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.13
      - attrs==22.2.0
      - babel==2.11.0
      - charset-normalizer==2.0.12
      - coverage==6.2
      - docutils==0.18.1
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==4.8.3
      - iniconfig==1.1.1
      - jinja2==3.0.3
      - markupsafe==2.0.1
      - mock==5.2.0
      - packaging==21.3
      - pluggy==1.0.0
      - py==1.11.0
      - pygments==2.14.0
      - pyparsing==3.1.4
      - pytest==7.0.1
      - pytz==2025.2
      - requests==2.27.1
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==5.3.0
      - sphinx-rtd-theme==2.0.0
      - sphinxcontrib-applehelp==1.0.2
      - sphinxcontrib-devhelp==1.0.2
      - sphinxcontrib-htmlhelp==2.0.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==1.0.3
      - sphinxcontrib-serializinghtml==1.1.5
      - tomli==1.2.3
      - typing-extensions==4.1.1
      - urllib3==1.26.20
      - zipp==3.6.0
prefix: /opt/conda/envs/nose2

nose2/tests/functional/test_layers_plugin.py::TestLayers::test_layer_reporter_output
nose2/tests/functional/support/scenario/layers/test_layers.py::Outer::test nose2/tests/functional/support/scenario/layers/test_layers.py::InnerA::test nose2/tests/functional/support/scenario/layers/test_layers.py::InnerA_1::test nose2/tests/functional/support/scenario/layers/test_layers.py::InnerB_1::test nose2/tests/functional/support/scenario/layers/test_layers.py::InnerC::test nose2/tests/functional/support/scenario/layers/test_layers.py::InnerC::test2 nose2/tests/functional/support/scenario/layers/test_layers.py::InnerD::test
nose2/tests/functional/support/scenario/layers/test_layers.py::NoLayer::test nose2/tests/functional/test_layers_plugin.py::TestLayers::test_layer_reporter_error_output nose2/tests/functional/test_layers_plugin.py::TestLayers::test_layers_and_attributes nose2/tests/functional/test_layers_plugin.py::TestLayers::test_layers_and_non_layers nose2/tests/functional/test_layers_plugin.py::TestLayers::test_methods_run_once_per_class nose2/tests/functional/test_layers_plugin.py::TestLayers::test_runs_layer_fixtures nose2/tests/functional/test_layers_plugin.py::TestLayers::test_scenario_fails_without_plugin nose2/tests/functional/test_layers_plugin.py::TestLayers::test_setup_fail nose2/tests/functional/test_layers_plugin.py::TestLayers::test_teardown_fail
nose2/plugins/layers.py
nose2/plugins/layers.py