Repository: conan-io/conan
Pull request: Fix CMake.test() target for Ninja Multi-Config
Changelog: Bugfix: Use correct build target in `CMake.test()` for the Ninja Multi-Config generator.
Docs: omit
Fixes #11405 

Problem statement:
[bug] `cmake.test()` cannot execute
### Environment Details (include every applicable attribute)
  * Operating System+version: Ubuntu 22.04 on WSL
  * Compiler+version: CMake 3.23.1
  * Conan version: 1.49.0
  * Python version: 3.10.4

### Steps to reproduce (Include if Applicable)

Put `cmake.test()` and run `conan build .` with `Ninja Multi-Config` as a generator.

### Logs (Executed commands with output) (Include/Attach if Applicable)

```
conanfile.py (mp-units/0.8.0): CMake command: cmake --build "/home/mpusz/repos/units/build-gcc-11" --config Release '--' '-j12'
[308/308] Linking CXX executable test/unit_test/runtime/Release/unit_tests_runtime
conanfile.py (mp-units/0.8.0): CMake command: cmake --build "/home/mpusz/repos/units/build-gcc-11" --config Release '--target' 'RUN_TESTS' '--' '-j12'
ninja: error: unknown target 'RUN_TESTS'
ERROR: conanfile.py (mp-units/0.8.0): Error in build() method, line 172
        cmake.test()
        ConanException: Error 1 while executing cmake --build "/home/mpusz/repos/units/build-gcc-11" --config Release '--target' 'RUN_TESTS' '--' '-j12'
```

CMake target `RUN_TESTS` is not available. `test` target works correctly but Conan does not use it for some reason.

Hints from issue discussion:
Yes, sounds that the test target is not taking into account ``Ninja Multi-Config`` generator. Seems the fix could be easy.

Commit message: Add unit test for the CMake.test() helper

Patch to review:
diff --git a/conan/tools/cmake/cmake.py b/conan/tools/cmake/cmake.py
index b3d6535a56a..0805f70922e 100644
--- a/conan/tools/cmake/cmake.py
+++ b/conan/tools/cmake/cmake.py
@@ -153,7 +153,8 @@ def test(self, build_type=None, target=None, cli_args=None, build_tool_args=None
             return
         if not target:
             is_multi = is_multi_configuration(self._generator)
-            target = "RUN_TESTS" if is_multi else "test"
+            is_ninja = "Ninja" in self._generator
+            target = "RUN_TESTS" if is_multi and not is_ninja else "test"
 
         self._build(build_type=build_type, target=target, cli_args=cli_args,
                     build_tool_args=build_tool_args)
diff --git a/conans/test/unittests/tools/cmake/test_cmake_test.py b/conans/test/unittests/tools/cmake/test_cmake_test.py
new file mode 100644
index 00000000000..897469529e3
--- /dev/null
+++ b/conans/test/unittests/tools/cmake/test_cmake_test.py
@@ -0,0 +1,42 @@
+import pytest
+
+from conan.tools.cmake import CMake
+from conan.tools.cmake.presets import write_cmake_presets
+from conans.client.conf import get_default_settings_yml
+from conans.model.conf import Conf
+from conans.model.settings import Settings
+from conans.test.utils.mocks import ConanFileMock
+from conans.test.utils.test_files import temp_folder
+
+
+@pytest.mark.parametrize("generator,target", [
+    ("NMake Makefiles", "test"),
+    ("Ninja Makefiles", "test"),
+    ("Ninja Multi-Config", "test"),
+    ("Unix Makefiles", "test"),
+    ("Visual Studio 14 2015", "RUN_TESTS"),
+    ("Xcode", "RUN_TESTS"),
+])
+def test_run_tests(generator, target):
+    """
+    Testing that the proper test target is picked for different generators, especially multi-config ones.
+    Issue related: https://github.com/conan-io/conan/issues/11405
+    """
+    settings = Settings.loads(get_default_settings_yml())
+    settings.os = "Windows"
+    settings.arch = "x86"
+    settings.build_type = "Release"
+    settings.compiler = "Visual Studio"
+    settings.compiler.runtime = "MDd"
+    settings.compiler.version = "14"
+
+    conanfile = ConanFileMock()
+    conanfile.conf = Conf()
+    conanfile.folders.generators = "."
+    conanfile.folders.set_base_generators(temp_folder())
+    conanfile.settings = settings
+
+    write_cmake_presets(conanfile, "toolchain", generator, {})
+    cmake = CMake(conanfile)
+    cmake.test()
+    assert "'--target' '%s'" % target in conanfile.command


Code review comments:
diff_hunk: @@ -0,0 +1,42 @@
+import pytest
+
+from conan.tools.cmake import CMake
+from conan.tools.cmake.presets import write_cmake_presets
+from conans.client.conf import get_default_settings_yml
+from conans.model.conf import Conf
+from conans.model.settings import Settings
+from conans.test.utils.mocks import ConanFileMock
+from conans.test.utils.test_files import temp_folder
+
+
+@pytest.mark.parametrize("generator,target", [
+    ("NMake Makefiles", "test"),
+    ("Ninja Makefiles", "test"),
+    ("Ninja Multi-Config", "test"),
+    ("Unix Makefiles", "test"),
+    ("Visual Studio 14 2015", "RUN_TESTS"),
+    ("Xcode", "RUN_TESTS"),
+])
+def test_run_tests(generator, target):
+    """
+    Testing that the proper test target is picked for different generators, especially multi-config ones.
+    Issue related: https://github.com/conan-io/conan/issues/11405
+    """
+    settings = Settings.loads(get_default_settings_yml())
+    settings.os = "Windows"
+    settings.arch = "x86"
+    settings.build_type = "Release"
+    settings.compiler = "Visual Studio"
+    settings.compiler.runtime = "MDd"
+    settings.compiler.version = "14"
+
+    conanfile = ConanFileMock()
+    conanfile.conf = Conf()
+    conanfile.folders.generators = "."
+    conanfile.folders.set_base_generators(temp_folder())
+    conanfile.settings = settings
+
+    write_cmake_presets(conanfile, "toolchain", generator, {})
+    cmake = CMake(conanfile)
+    cmake.test()
+    assert "'--target' '%s'" % target in conanfile.command
path: conans/test/unittests/tools/cmake/test_cmake_test.py
text: @user1:
```suggestion
    if platform.system() == "Windows":
        assert "--target %s" % target in conanfile.command
    else:
        assert "'--target' '%s'" % target in conanfile.command
```

There is a small difference atm in the command in Windows, the args are not quoted.

@user1:
cc/ @user2 This is one of the things related to https://github.com/conan-io/conan/pull/11553, that seems a bit weird to me, that the commands quoting is different in different systems.

@author:
Thank you for the suggestion. I added the `platform` import and made the search pattern conditional on the platform.