Repository: conan-io/conan

Issue:
Optionally Skip Testing When Cross Building
I am cross compiling libraries with test_packages which cannot be built for the target platform. Currently, this causes unnecessary build failures because the test_package build fails due to incompatibility with the platform. I would like to specify on the command line that test failures should not cause this build to fail because I know that these failures are false positives. 

While it can be argued that all code should always be tested for all platforms, doing so is not feasible in my case since it would require adding large amounts of platform specific code to the test_package and running the executable in an emulator. Currently, the simplest solution to this problem is to run `export` and `install` manually, but doing so is inconvenient and it's easy to forget to `export`. Adding more sophisticated options to each conanfile is perhaps more clean but requires additional work in each used package which may be maintained by third parties.

To fix this issue, a simple `--no-test` flag should be added to `conan create`.

*EDIT*: I just noticed that test_packages are only run for the current package, not those being built using `--build`. Originally, I detailed a system that allowed selectively disabling tests, but this fact greatly simplifies the issue.


Discussion:
I think that naming the test_package differently to *test* and *test_package*, then providing its name with ``-tf`` argument would be good enough. As this process should probably be done in CI, forgetting about this shouldn't be a big issue.

I would say that adding an extra argument will further clutter the command line, which already has many parameters. What about using ``conan create -tf=None`` (read it as "the test folder is None = there is no test folder")? In that case, it should be an easy feature, I wouldn't oppose to it.
Thanks for the feedback!

I did consider renaming the test_package but this is more of a workaround in my opinion. Currently, I can compile most packages by just specifying a profile and maybe a few other flags. Using this workaround, I'd have to move the test folder in existing packages which complicates the build and is not very intuitive. I also want to run my tests by default since I'm using TDD and having to specify `-tf` every time would be somewhat irritating. Cross compiling happens less frequently and already requires specifying a profile, so adding another flag in that case isn't too bad.

Using `-tf=None` would be just as good as adding `--no-test` from an end-user perspective, so I'd be in favor of this solution.
Ok, lets do it that way then!

Resolving patch:
diff --git a/conans/client/command.py b/conans/client/command.py
--- a/conans/client/command.py
+++ b/conans/client/command.py
@@ -168,7 +168,8 @@ def create(self, *args):
         parser.add_argument("-ne", "--not-export", default=False, action='store_true',
                             help='Do not export the conanfile')
         parser.add_argument("-tf", "--test-folder", action=OnceArgument,
-                            help='alternative test folder name, by default is "test_package"')
+                            help='alternative test folder name, by default is "test_package". '
+                                 '"None" if test stage needs to be disabled')
         parser.add_argument('-k', '--keep-source', default=False, action='store_true',
                             help='Optional. Do not remove the source folder in local cache. '
                                  'Use for testing purposes only')
@@ -183,6 +184,10 @@ def create(self, *args):
 
         name, version, user, channel = get_reference_fields(args.reference)
 
+        if args.test_folder == "None":
+            # Now if parameter --test-folder=None (string None) we have to skip tests
+            args.test_folder = False
+
         return self._conan.create(args.path, name, version, user, channel,
                                   args.profile, args.settings, args.options,
                                   args.env, args.test_folder, args.not_export,
diff --git a/conans/client/conan_api.py b/conans/client/conan_api.py
--- a/conans/client/conan_api.py
+++ b/conans/client/conan_api.py
@@ -229,7 +229,13 @@ def create(self, conanfile_path, name=None, version=None, user=None, channel=Non
                keep_source=False, keep_build=False, verify=None,
                manifests=None, manifests_interactive=None,
                remote=None, update=False, cwd=None):
+        """
+        API method to create a conan package
 
+        :param test_folder: default None   - looks for default 'test' or 'test_package' folder),
+                                    string - test_folder path
+                                    False  - disabling tests
+        """
         settings = settings or []
         options = options or []
         env = env or []
@@ -262,7 +268,12 @@ def create(self, conanfile_path, name=None, version=None, user=None, channel=Non
                                     cwd, self._client_cache)
 
         def get_test_conanfile_path(tf):
-            """Searchs in the declared test_folder or in the standard locations"""
+            """Searches in the declared test_folder or in the standard locations"""
+
+            if tf is False:
+                # Look up for testing conanfile can be disabled if tf (test folder) is False
+                return None
+
             test_folders = [tf] if tf else ["test_package", "test"]
             base_folder = os.path.dirname(conanfile_path)
             for test_folder_name in test_folders:


Test patch:
diff --git a/conans/test/command/create_test.py b/conans/test/command/create_test.py
--- a/conans/test/command/create_test.py
+++ b/conans/test/command/create_test.py
@@ -91,7 +91,6 @@ class MyPkg(ConanFile):
         self.assertTrue(error)
         self.assertIn("ERROR: --keep-build specified, but build folder not found", client.out)
 
-
     def create_test(self):
         client = TestClient()
         client.save({"conanfile.py": """
@@ -234,6 +233,25 @@ def test(self):
         self.assertIn("Pkg/0.1@lasote/testing: Generating the package", client.out)
         self.assertIn("Pkg/0.1@lasote/testing (test package): TESTING!!!", client.out)
 
+    def create_skip_test_package_test(self):
+        """
+        Skip the test package stage if explicitly disabled with --test-folder=None
+        """
+        # https://github.com/conan-io/conan/issues/2355
+        client = TestClient()
+        client.save({"conanfile.py": """from conans import ConanFile
+class MyPkg(ConanFile):
+    name = "Pkg"
+    version = "0.1"
+""", "test_package/conanfile.py": """from conans import ConanFile
+class MyTest(ConanFile):
+    def test(self):
+        self.output.info("TESTING!!!")
+"""})
+        client.run("create . lasote/testing --test-folder=None")
+        self.assertIn("Pkg/0.1@lasote/testing: Generating the package", client.out)
+        self.assertNotIn("Pkg/0.1@lasote/testing (test package): TESTING!!!", client.out)
+
     def create_test_package_requires(self):
         client = TestClient()
         dep_conanfile = """from conans import ConanFile