little-dude: I need to add a test for this before merging.
@slemesle let me know if you want to be the author of this commit, since you proposed the fix.
diff --git a/nose2/plugins/junitxml.py b/nose2/plugins/junitxml.py
index c90450e..e61a08b 100644
--- a/nose2/plugins/junitxml.py
+++ b/nose2/plugins/junitxml.py
@@ -4,15 +4,71 @@ Output test reports in junit-xml format.
 This plugin implements :func:`startTest`, :func:`testOutcome` and
 :func:`stopTestRun` to compile and then output a test report in
 junit-xml format. By default, the report is written to a file called
-``nose2-junit.xml`` in the current working directory. 
+``nose2-junit.xml`` in the current working directory.
 
 You can configure the output filename by setting ``path`` in a ``[junit-xml]``
 section in a config file.  Unicode characters which are invalid in XML 1.0
-are replaced with the ``U+FFFD`` replacement character.  In the case that your
-software throws an error with an invalid byte string.  
+are replaced with the ``U+FFFD`` replacement character. In the case that your
+software throws an error with an invalid byte string.
 
-By default, the ranges of discouraged characters are replaced as well.  This can be
-changed by setting the ``keep_restricted`` configuration variable to ``True``.
+By default, the ranges of discouraged characters are replaced as well. This can
+be changed by setting the ``keep_restricted`` configuration variable to
+``True``.
+
+By default, the arguments of parametrized and generated tests are not printed.
+For instance, the following code:
+
+.. code-block:: python
+
+    # a.py
+
+    from nose2 import tools
+
+    def test_gen():
+        def check(a, b):
+            assert a == b, '{}!={}'.format(a,b)
+
+        yield check, 99, 99
+        yield check, -1, -1
+
+    @tools.params('foo', 'bar')
+    def test_params(arg):
+        assert arg in ['foo', 'bar', 'baz']
+
+Produces this XML by default:
+
+.. code-block:: xml
+
+    <testcase classname="a" name="test_gen:1" time="0.000171">
+        <system-out />
+    </testcase>
+    <testcase classname="a" name="test_gen:2" time="0.000202">
+        <system-out />
+    </testcase>
+    <testcase classname="a" name="test_params:1" time="0.000159">
+        <system-out />
+    </testcase>
+    <testcase classname="a" name="test_params:2" time="0.000163">
+        <system-out />
+    </testcase>
+
+But if ``test_fullname`` is ``True``, then the following XML is
+produced:
+
+.. code-block:: xml
+
+    <testcase classname="a" name="test_gen:1 (99, 99)" time="0.000213">
+        <system-out />
+    </testcase>
+    <testcase classname="a" name="test_gen:2 (-1, -1)" time="0.000194">
+        <system-out />
+    </testcase>
+    <testcase classname="a" name="test_params:1 ('foo')" time="0.000178">
+        <system-out />
+    </testcase>
+    <testcase classname="a" name="test_params:2 ('bar')" time="0.000187">
+        <system-out />
+    </testcase>
 
 """
 # Based on unittest2/plugins/junitxml.py,
@@ -39,10 +95,12 @@ class JUnitXmlReporter(events.Plugin):
     def __init__(self):
         self.path = os.path.realpath(
             self.config.as_str('path', default='nose2-junit.xml'))
-        self.keep_restricted = self.config.as_bool('keep_restricted',
-                                                   default=False)
-        self.test_properties = self.config.as_str('test_properties',
-                                                  default=None)
+        self.keep_restricted = self.config.as_bool(
+            'keep_restricted', default=False)
+        self.test_properties = self.config.as_str(
+            'test_properties', default=None)
+        self.test_fullname = self.config.as_bool(
+            'test_fullname', default=False)
         if self.test_properties is not None:
             self.test_properties_path = os.path.realpath(self.test_properties)
         self.errors = 0
@@ -60,11 +118,15 @@ class JUnitXmlReporter(events.Plugin):
     def testOutcome(self, event):
         """Add test outcome to xml tree"""
         test = event.test
-        testid = test.id().split('\n')[0]
-        # split into module, class, method parts... somehow
+        testid_lines = test.id().split('\n')
+        testid = testid_lines[0]
         parts = testid.split('.')
         classname = '.'.join(parts[:-1])
         method = parts[-1]
+        # for generated test cases
+        if len(testid_lines) > 1 and self.test_fullname:
+            test_args = ':'.join(testid_lines[1:])
+            method = '%s (%s)' % (method, test_args)
 
         testcase = ET.SubElement(self.tree, 'testcase')
         testcase.set('time', "%.6f" % self._time())

junit-xml does not output generated tests parameters
I use generated tests with meaningfull parameters and I wish I could see them exported in junit-xml report. 


The patch looks pretty simple (junitxml.py): 

```python
    def testOutcome(self, event):
        """Add test outcome to xml tree"""
        test = event.test
        testid_lines = test.id().split('\n')
        testid = testid_lines[0]
        # split into module, class, method parts... somehow
        parts = testid.split('.')
        classname = '.'.join(parts[:-1])
        method = parts[-1]
        if len(testid_lines) > 1:
            method = '%s:' % method + ':'.join(testid_lines[1:])
```

With this one we can have all parameters as requested.

diff --git a/nose2/tests/unit/test_junitxml.py b/nose2/tests/unit/test_junitxml.py
index 6ffef43..706daa2 100644
--- a/nose2/tests/unit/test_junitxml.py
+++ b/nose2/tests/unit/test_junitxml.py
@@ -186,6 +186,20 @@ class TestJunitXmlPlugin(TestCase):
         self.assertEqual(xml[0].get('name'), 'test_gen:1')
         self.assertEqual(xml[1].get('name'), 'test_gen:2')
 
+    def test_generator_test_full_name_correct(self):
+        gen = generators.Generators(session=self.session)
+        gen.register()
+        self.plugin.test_fullname = True
+        event = events.LoadFromTestCaseEvent(self.loader, self.case)
+        self.session.hooks.loadTestsFromTestCase(event)
+        cases = event.extraTests
+        for case in cases:
+            case(self.result)
+        xml = self.plugin.tree.findall('testcase')
+        self.assertEqual(len(xml), 2)
+        self.assertEqual(xml[0].get('name'), 'test_gen:1 (1, 1)')
+        self.assertEqual(xml[1].get('name'), 'test_gen:2 (1, 2)')
+
     def test_params_test_name_correct(self):
         # param test loading is a bit more complex than generator
         # loading. XXX -- can these be reconciled so they both
@@ -213,6 +227,31 @@ class TestJunitXmlPlugin(TestCase):
         self.assertEqual(params[1].get('name'), 'test_params:2')
         self.assertEqual(params[2].get('name'), 'test_params:3')
 
+    def test_params_test_full_name_correct(self):
+        plug1 = parameters.Parameters(session=self.session)
+        plug1.register()
+        plug2 = testcases.TestCaseLoader(session=self.session)
+        plug2.register()
+        # need module to fire top-level event
+
+        class Mod(object):
+            pass
+
+        m = Mod()
+        m.Test = self.case
+        event = events.LoadFromModuleEvent(self.loader, m)
+        self.plugin.test_fullname = True
+        self.session.hooks.loadTestsFromModule(event)
+        for case in event.extraTests:
+            case(self.result)
+        xml = self.plugin.tree.findall('testcase')
+        self.assertEqual(len(xml), 12)
+        params = [x for x in xml if x.get('name').startswith('test_params')]
+        self.assertEqual(len(params), 3)
+        self.assertEqual(params[0].get('name'), 'test_params:1 (1)')
+        self.assertEqual(params[1].get('name'), 'test_params:2 (2)')
+        self.assertEqual(params[2].get('name'), 'test_params:3 (3)')
+
     def test_writes_xml_file_at_end(self):
         test = self.case('test')
         test(self.result)

pip install -e .
parse_log_pytest
requirements.txt
nose2 pytest
apt-get update apt-get install -y gcc
3.7
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi @ file:///croot/certifi_1671487769961/work/certifi
cov-core==1.15.0
coverage==7.2.7
exceptiongroup==1.2.2
importlib-metadata==6.7.0
iniconfig==2.0.0
-e git+https://github.com/nose-devs/nose2.git@bbf5897eb1aa224100e86ba594042e4399fd2f5f#egg=nose2
packaging==24.0
pluggy==1.2.0
pytest==7.4.4
six==1.17.0
tomli==2.0.1
typing_extensions==4.7.1
zipp==3.15.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=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - 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=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - cov-core==1.15.0
      - coverage==7.2.7
      - exceptiongroup==1.2.2
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - packaging==24.0
      - pluggy==1.2.0
      - pytest==7.4.4
      - six==1.17.0
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - zipp==3.15.0
prefix: /opt/conda/envs/nose2

nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_generator_test_full_name_correct nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_params_test_full_name_correct
nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_error_bad_xml nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_error_bad_xml_b nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_error_bad_xml_b_keep nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_error_bad_xml_keep nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_error_includes_traceback nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_failure_includes_traceback nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_generator_test_name_correct nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_params_test_name_correct nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_skip_includes_skipped nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_success_added_to_xml nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_writes_xml_file_at_end nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_xml_contains_empty_system_err_without_logcapture nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_xml_contains_log_message_in_system_err_with_logcapture nose2/tests/unit/test_junitxml.py::TestJunitXmlPlugin::test_xml_file_path_is_not_affected_by_chdir_in_test
nose2/plugins/junitxml.py
nose2/plugins/junitxml.py