Repository: conan-io/conan

Issue:
Custom folder name in conan test command
When people integrates Conan inside the project the name "test" is commonly overlapped with project tests folder.

Make conan test command use the subfolders layout
So the test code and files is not copied to every build/sha folder, but referenced instead. The build folder will live under the test folder, not the root one.



Discussion:

Resolving patch:
diff --git a/conans/client/command.py b/conans/client/command.py
--- a/conans/client/command.py
+++ b/conans/client/command.py
@@ -21,7 +21,6 @@
 from conans.model.version import Version
 from conans.client.migrations import ClientMigrator
 import hashlib
-import shutil
 from conans.util.files import rmdir, load
 from argparse import RawTextHelpFormatter
 import re
@@ -129,15 +128,16 @@ def test(self, *args):
         """
         parser = argparse.ArgumentParser(description=self.test.__doc__, prog="conan test",
                                          formatter_class=RawTextHelpFormatter)
-        parser.add_argument("path", nargs='?', default="",
-                            help='path to conanfile file, '
+        parser.add_argument("path", nargs='?', default="", help='path to conanfile file, '
                             'e.g. /my_project/')
+        parser.add_argument("-f", "--folder", help='alternative test folder name')
         self._parse_args(parser)
 
         args = parser.parse_args(*args)
+        test_folder_name = args.folder or "test"
 
         root_folder = os.path.normpath(os.path.join(os.getcwd(), args.path))
-        test_folder = os.path.join(root_folder, "test")
+        test_folder = os.path.join(root_folder, test_folder_name)
         if not os.path.exists(test_folder):
             raise ConanException("test folder not available")
 
@@ -153,20 +153,20 @@ def test(self, *args):
         settings = args.settings or []
 
         sha = hashlib.sha1("".join(options + settings).encode()).hexdigest()
-        build_folder = os.path.join(root_folder, "build", sha)
+        build_folder = os.path.join(test_folder, "build", sha)
         rmdir(build_folder)
-        shutil.copytree(test_folder, build_folder)
+        # shutil.copytree(test_folder, build_folder)
 
         options = self._get_tuples_list_from_extender_arg(args.options)
         settings = self._get_tuples_list_from_extender_arg(args.settings)
 
-        self._manager.install(reference=build_folder,
+        self._manager.install(reference=test_folder,
                               current_path=build_folder,
                               remote=args.remote,
                               options=options,
                               settings=settings,
                               build_mode=args.build)
-        self._manager.build(build_folder, build_folder, test=True)
+        self._manager.build(test_folder, build_folder, test=True)
 
     def install(self, *args):
         """ install in the local store the given requirements.
diff --git a/conans/client/manager.py b/conans/client/manager.py
--- a/conans/client/manager.py
+++ b/conans/client/manager.py
@@ -137,7 +137,7 @@ def install(self, reference, current_path, remote=None, options=None, settings=N
         @param current_path: where the output files will be saved
         @param remote: install only from that remote
         @param options: list of tuples: [(optionname, optionvalue), (optionname, optionvalue)...]
-        @param settings: list of tuples: [(settingname, settingvalue), (settingname, settingvalue)...]
+        @param settings: list of tuples: [(settingname, settingvalue), (settingname, value)...]
         """
         reference_given = True
         if not isinstance(reference, ConanFileReference):
@@ -274,6 +274,7 @@ def build(self, conanfile_path, current_path, test=False, filename=None):
                     pass
 
             os.chdir(current_path)
+            conan_file._conanfile_directory = conanfile_path
             conan_file.build()
             if test:
                 conan_file.test()
@@ -369,4 +370,3 @@ def remove(self, pattern, src=False, build_ids=None, package_ids_filter=None, fo
     def user(self, remote=None, name=None, password=None):
         remote_proxy = ConanProxy(self._paths, self._user_io, self._remote_manager, remote)
         return remote_proxy.authenticate(name, password)
-        


Test patch:
diff --git a/conans/test/integration/complete_test.py b/conans/test/integration/complete_test.py
--- a/conans/test/integration/complete_test.py
+++ b/conans/test/integration/complete_test.py
@@ -16,7 +16,7 @@ def setUp(self):
                                  [],  # write permissions
                                  users={"lasote": "mypass"})  # exported users and passwords
         self.servers = {"default": test_server}
-        self.client = TestClient(servers=self.servers, users={"default":[("lasote", "mypass")]})
+        self.client = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
 
     def reuse_test(self):
         conan_reference = ConanFileReference.loads("Hello0/0.1@lasote/stable")
@@ -49,7 +49,7 @@ def reuse_test(self):
         self._assert_library_exists_in_server(package_ref, server_paths)
 
         # Now from other "computer" install the uploaded conans with same options (nothing)
-        other_conan = TestClient(servers=self.servers, users={"default":[("lasote", "mypass")]})
+        other_conan = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
         other_conan.run("install %s --build missing" % str(conan_reference))
         # Build should be empty
         build_path = other_conan.paths.build(package_ref)
@@ -66,7 +66,7 @@ def reuse_test(self):
             ref = PackageReference(conan_reference, package_id)
             self._assert_library_exists(ref, other_conan.paths)
 
-        client3 = TestClient(servers=self.servers, users={"default":[("lasote", "mypass")]})  # Mocked userio
+        client3 = TestClient(servers=self.servers, users={"default": [("lasote", "mypass")]})
         conan_reference = ConanFileReference.loads("Hello1/0.2@lasote/stable")
         files3 = cpp_hello_conan_files("Hello1", "0.1", ["Hello0/0.1@lasote/stable"])
         client3.save(files3)
diff --git a/conans/test/integration/conan_test_test.py b/conans/test/integration/conan_test_test.py
--- a/conans/test/integration/conan_test_test.py
+++ b/conans/test/integration/conan_test_test.py
@@ -27,7 +27,7 @@ class HelloReuseConan(ConanFile):
 
     def build(self):
         cmake = CMake(self.settings)
-        self.run('cmake %s' % cmake.command_line)
+        self.run('cmake "%s" %s' % (self.conanfile_directory, cmake.command_line))
         self.run("cmake --build . %s" % cmake.build_config)
 
     def test(self):