Leverage latest pylint features 12/73012/2
authorCédric Ollivier <cedric.ollivier@orange.com>
Tue, 9 Nov 2021 10:22:02 +0000 (11:22 +0100)
committerCédric Ollivier <cedric.ollivier@orange.com>
Tue, 9 Nov 2021 12:22:19 +0000 (13:22 +0100)
It adds encoding in all open call and leverage f-strings.

Change-Id: I70ccd2bfcadae44929d5874f98fa3bf4ff644488
Signed-off-by: Cédric Ollivier <cedric.ollivier@orange.com>
(cherry picked from commit 17739d718901a10f7ec0aaf9a6d53141294a347d)

20 files changed:
test-requirements.txt
tox.ini
upper-constraints.txt
xtesting/ci/run_tests.py
xtesting/ci/tier_builder.py
xtesting/core/behaveframework.py
xtesting/core/campaign.py
xtesting/core/feature.py
xtesting/core/mts.py
xtesting/core/robotframework.py
xtesting/core/testcase.py
xtesting/core/unit.py
xtesting/core/vnf.py
xtesting/tests/unit/ci/test_run_tests.py
xtesting/tests/unit/core/test_behaveframework.py
xtesting/tests/unit/core/test_feature.py
xtesting/tests/unit/core/test_robotframework.py
xtesting/tests/unit/core/test_unit.py
xtesting/tests/unit/utils/test_decorators.py
xtesting/utils/decorators.py

index 0bfae30..4ba8a8f 100644 (file)
@@ -11,6 +11,6 @@ sphinx-rtd-theme
 yamllint
 doc8 # Apache-2.0
 bashate # Apache-2.0
-ansible-lint
+ansible-lint[core]
 bandit
 munch # MIT
diff --git a/tox.ini b/tox.ini
index dca93ba..0175731 100644 (file)
--- a/tox.ini
+++ b/tox.ini
@@ -48,7 +48,7 @@ commands =
 [testenv:ansiblelint]
 basepython = python3.9
 commands =
-  ansible-lint -x303,305,306 ansible/site.yml
+  ansible-lint -xcommand-instead-of-module,command-instead-of-shell,risky-shell-pipe ansible/site.yml
 
 [testenv:py38]
 commands = nosetests xtesting/tests/unit
index e3e6b64..32e09e1 100644 (file)
@@ -1,8 +1,8 @@
 robotframework===4.1.2
-bandit===1.1.0
+bandit===1.7.0
 behave===1.2.6
-behave-html-formatter===0.9.4
-pylint===2.9.6
-flake8===3.9.2
+behave-html-formatter===0.9.8
+pylint===2.11.1
+flake8===4.0.1
 nose===1.3.7
-ansible-lint===4.3.7
+ansible-lint===5.2.1
index cf7fe42..bc2b43d 100644 (file)
@@ -97,7 +97,7 @@ class Runner():
         if not os.path.isfile(rc_file):
             LOGGER.debug("No env file %s found", rc_file)
             return
-        with open(rc_file, "r") as rcfd:
+        with open(rc_file, "r", encoding='utf-8') as rcfd:
             for line in rcfd:
                 var = (line.rstrip('"\n').replace('export ', '').split(
                     "=") if re.search(r'(.*)=(.*)', line) else None)
@@ -115,7 +115,7 @@ class Runner():
     def get_dict_by_test(testname):
         # pylint: disable=missing-docstring
         with open(pkg_resources.resource_filename(
-                'xtesting', 'ci/testcases.yaml')) as tyaml:
+                'xtesting', 'ci/testcases.yaml'), encoding='utf-8') as tyaml:
             testcases_yaml = yaml.safe_load(tyaml)
         for dic_tier in testcases_yaml.get("tiers"):
             for dic_testcase in dic_tier['testcases']:
@@ -209,8 +209,8 @@ class Runner():
                     self.overall_result = Result.EX_ERROR
                     if test.is_blocking():
                         raise BlockingTestFailed(
-                            "The test case {} failed and is blocking".format(
-                                test.get_name()))
+                            f"The test case {test.get_name()} "
+                            "failed and is blocking")
         return self.overall_result
 
     def run_all(self):
@@ -310,7 +310,7 @@ def main():
         os.makedirs(constants.RESULTS_DIR)
     except OSError as ex:
         if ex.errno != errno.EEXIST:
-            print("{} {}".format("Cannot create", constants.RESULTS_DIR))
+            print(f"Cannot create {constants.RESULTS_DIR}")
             return testcase.TestCase.EX_RUN_ERROR
     if env.get('DEBUG').lower() == 'true':
         logging.config.fileConfig(pkg_resources.resource_filename(
index 9b8ac7d..7658b7c 100644 (file)
@@ -29,7 +29,7 @@ class TierBuilder():
         self.generate_tiers()
 
     def read_test_yaml(self):
-        with open(self.testcases_file) as tc_file:
+        with open(self.testcases_file, encoding='utf-8') as tc_file:
             self.testcases_yaml = yaml.safe_load(tc_file)
 
         self.dic_tier_array = []
index 3dc6038..6003c4a 100644 (file)
@@ -41,7 +41,7 @@ class BehaveFramework(testcase.TestCase):
 
     def parse_results(self):
         """Parse output.json and get the details in it."""
-        with open(self.json_file) as stream_:
+        with open(self.json_file, encoding='utf-8') as stream_:
             self.response = json.load(stream_)
             if self.response:
                 self.total_tests = len(self.response)
@@ -87,11 +87,11 @@ class BehaveFramework(testcase.TestCase):
             except Exception:  # pylint: disable=broad-except
                 self.__logger.exception("Cannot create %s", self.res_dir)
                 return self.EX_RUN_ERROR
-        config = ['--junit', '--junit-directory={}'.format(self.res_dir),
-                  '--format=json', '--outfile={}'.format(self.json_file)]
+        config = ['--junit', f'--junit-directory={self.res_dir}',
+                  '--format=json', f'--outfile={self.json_file}']
         html_file = os.path.join(self.res_dir, 'output.html')
         config += ['--format=behave_html_formatter:HTMLFormatter',
-                   '--outfile={}'.format(html_file)]
+                   f'--outfile={html_file}']
         if kwargs.get("tags", False):
             config += ['--tags='+','.join(kwargs.get("tags", []))]
         if kwargs.get("console", False):
index 5874768..5c5744e 100644 (file)
@@ -69,7 +69,7 @@ class Campaign():
         try:
             url = env.get('TEST_DB_URL')
             req = requests.get(
-                "{}?build_tag={}".format(url, env.get('BUILD_TAG')),
+                f"{url}?build_tag={env.get('BUILD_TAG')}",
                 headers=testcase.TestCase.headers)
             req.raise_for_status()
             output = req.json()
@@ -78,10 +78,11 @@ class Campaign():
                 for j, _ in enumerate(
                         output["results"][i]["details"]["links"]):
                     output["results"][i]["details"]["links"][j] = re.sub(
-                        "^{}/*".format(os.environ["HTTP_DST_URL"]), '',
+                        "^{os.environ['HTTP_DST_URL']}/*", '',
                         output["results"][i]["details"]["links"][j])
             Campaign.__logger.debug("data to archive: \n%s", output)
-            with open("{}.json".format(env.get('BUILD_TAG')), "w") as dfile:
+            with open("{env.get('BUILD_TAG')}.json", "w",
+                      encoding='utf-8') as dfile:
                 json.dump(output, dfile)
         except Exception:  # pylint: disable=broad-except
             Campaign.__logger.exception(
@@ -126,19 +127,19 @@ class Campaign():
             prefix = os.path.join(s3path, build_tag)
             # pylint: disable=no-member
             for s3_object in b3resource.Bucket(bucket_name).objects.filter(
-                    Prefix="{}/".format(prefix)):
+                    Prefix=f"{prefix}/"):
                 path, _ = os.path.split(s3_object.key)
-                lpath = re.sub('^{}/*'.format(s3path), '', path)
+                lpath = re.sub(f'^{s3path}/*', '', path)
                 if lpath and not os.path.exists(lpath):
                     os.makedirs(lpath)
                 # pylint: disable=no-member
                 b3resource.Bucket(bucket_name).download_file(
                     s3_object.key,
-                    re.sub('^{}/*'.format(s3path), '', s3_object.key),
+                    re.sub(f'^{s3path}/*', '', s3_object.key),
                     Config=config)
                 Campaign.__logger.info(
                     "Downloading %s",
-                    re.sub('^{}/*'.format(s3path), '', s3_object.key))
+                    re.sub(f'^{s3path}/*', '', s3_object.key))
             return Campaign.EX_OK
         except Exception:  # pylint: disable=broad-except
             Campaign.__logger.exception("Cannot publish the artifacts")
@@ -171,9 +172,9 @@ class Campaign():
             build_tag = env.get('BUILD_TAG')
             assert Campaign.dump_db() == Campaign.EX_OK
             assert Campaign.dump_artifacts() == Campaign.EX_OK
-            with zipfile.ZipFile('{}.zip'.format(build_tag),
+            with zipfile.ZipFile(f'{build_tag}.zip',
                                  'w', zipfile.ZIP_DEFLATED) as zfile:
-                zfile.write("{}.json".format(build_tag))
+                zfile.write(f"{build_tag}.json")
                 for root, _, files in os.walk(build_tag):
                     for filename in files:
                         zfile.write(os.path.join(root, filename))
@@ -184,17 +185,17 @@ class Campaign():
                 "S3_ENDPOINT_URL"] else 8 * 1024 * 1024
             config = TransferConfig(multipart_threshold=multipart_threshold)
             bucket_name = urlparse(dst_s3_url).netloc
-            mime_type = mimetypes.guess_type('{}.zip'.format(build_tag))
+            mime_type = mimetypes.guess_type(f'{build_tag}.zip')
             path = urlparse(dst_s3_url).path.strip("/")
             # pylint: disable=no-member
             b3resource.Bucket(bucket_name).upload_file(
-                '{}.zip'.format(build_tag),
-                os.path.join(path, '{}.zip'.format(build_tag)),
+                f'{build_tag}.zip',
+                os.path.join(path, f'{build_tag}.zip'),
                 Config=config,
                 ExtraArgs={'ContentType': mime_type[
                     0] or 'application/octet-stream'})
             dst_http_url = os.environ["HTTP_DST_URL"]
-            link = os.path.join(dst_http_url, '{}.zip'.format(build_tag))
+            link = os.path.join(dst_http_url, f'{build_tag}.zip')
             Campaign.__logger.info(
                 "All data were successfully published:\n\n%s", link)
             return Campaign.EX_OK
index 5a02bb6..8cc9a21 100644 (file)
@@ -86,7 +86,7 @@ class BashFeature(Feature):
 
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
-        self.result_file = "{}/{}.log".format(self.res_dir, self.case_name)
+        self.result_file = f"{self.res_dir}/{self.case_name}.log"
 
     def execute(self, **kwargs):
         """Execute the cmd passed as arg
@@ -105,7 +105,7 @@ class BashFeature(Feature):
             max_duration = kwargs.get("max_duration")
             if not os.path.isdir(self.res_dir):
                 os.makedirs(self.res_dir)
-            with open(self.result_file, 'w') as f_stdout:
+            with open(self.result_file, 'w', encoding='utf-8') as f_stdout:
                 self.__logger.info("Calling %s", cmd)
                 with subprocess.Popen(
                         cmd, shell=True, stdout=subprocess.PIPE,
@@ -122,7 +122,7 @@ class BashFeature(Feature):
                             "Killing process after %d second(s).",
                             max_duration)
                         return -2
-            with open(self.result_file, 'r') as f_stdin:
+            with open(self.result_file, 'r', encoding='utf-8') as f_stdin:
                 self.__logger.debug("$ %s\n%s", cmd, f_stdin.read().rstrip())
             return process.returncode
         except KeyError:
index 3bc7bde..0f15733 100644 (file)
@@ -65,7 +65,7 @@ class MTSLauncher(feature.BashFeature):
         """Parse testPlan.csv containing the status of each testcase of the test file.
         See sample file in `xtesting/samples/mts/output/testPlan.csv`
         """
-        with open(self.mts_result_csv_file) as stream_:
+        with open(self.mts_result_csv_file, encoding='utf-8') as stream_:
             self.__logger.info("Parsing file : %s", self.mts_result_csv_file)
             reader = csv.reader(stream_, delimiter=';')
             rownum = 0
@@ -183,18 +183,13 @@ class MTSLauncher(feature.BashFeature):
                     return -3
 
             # Build command line to launch for MTS
-            cmd = ("cd {} && ./startCmd.sh {} {} -sequential -levelLog:{}"
-                   " -storageLog:{}"
-                   " -config:stats.REPORT_DIRECTORY+{}"
-                   " -config:logs.STORAGE_DIRECTORY+{}"
+            cmd = (f"cd {cwd} && ./startCmd.sh {test_file} "
+                   f"{enabled_testcases_str} -sequential -levelLog:{log_level}"
+                   f" -storageLog:{store_method}"
+                   f" -config:stats.REPORT_DIRECTORY+{self.mts_stats_dir}"
+                   f" -config:logs.STORAGE_DIRECTORY+{self.mts_logs_dir}"
                    " -genReport:true"
-                   " -showRep:false").format(cwd,
-                                             test_file,
-                                             enabled_testcases_str,
-                                             log_level,
-                                             store_method,
-                                             self.mts_stats_dir,
-                                             self.mts_logs_dir)
+                   " -showRep:false")
 
             # Make sure to create the necessary output sub-folders for MTS
             # and cleanup output files from previous run.
index 3a439ec..775ed1c 100644 (file)
@@ -79,9 +79,9 @@ class RobotFramework(testcase.TestCase):
         result = robot.api.ExecutionResult(self.xml_file)
         writer = resultwriter.ResultWriter(result)
         return writer.write_results(
-            report='{}/report.html'.format(self.res_dir),
-            log='{}/log.html'.format(self.res_dir),
-            xunit='{}/xunit.xml'.format(self.res_dir))
+            report=f'{self.res_dir}/report.html',
+            log=f'{self.res_dir}/log.html',
+            xunit=f'{self.res_dir}/xunit.xml')
 
     def run(self, **kwargs):
         """Run the RobotFramework suites
index 672ba3f..f7814f7 100644 (file)
@@ -105,9 +105,10 @@ class TestCase(metaclass=abc.ABCMeta):
             assert self.stop_time
             if self.stop_time < self.start_time:
                 return "XX:XX"
-            return "{}:{}".format(
-                str(int(self.stop_time - self.start_time) // 60).zfill(2),
-                str(int(self.stop_time - self.start_time) % 60).zfill(2))
+            return(
+                f"{str(int(self.stop_time - self.start_time) // 60).zfill(2)}:"
+                f"{str(int(self.stop_time - self.start_time) % 60).zfill(2)}")
+
         except Exception:  # pylint: disable=broad-except
             self.__logger.error("Please run test before getting the duration")
             return "XX:XX"
@@ -314,7 +315,7 @@ class TestCase(metaclass=abc.ABCMeta):
                         ExtraArgs={'ContentType': mime_type[
                             0] or 'application/octet-stream'})
                     link = os.path.join(dst_http_url, log_file)
-                    output_str += "\n{}".format(link)
+                    output_str += f"\n{link}"
                     self.details["links"].append(link)
             for root, _, files in os.walk(self.res_dir):
                 for pub_file in files:
@@ -334,7 +335,7 @@ class TestCase(metaclass=abc.ABCMeta):
                     link = os.path.join(dst_http_url, os.path.relpath(
                         os.path.join(root, pub_file),
                         start=self.dir_results))
-                    output_str += "\n{}".format(link)
+                    output_str += f"\n{link}"
                     self.details["links"].append(link)
             self.__logger.info(
                 "All artifacts were successfully published: %s\n", output_str)
index e6c3cd8..10feb88 100644 (file)
@@ -56,7 +56,7 @@ class Suite(testcase.TestCase):
             Exception
         """
         stream.seek(0)
-        with open("{}/results.xml".format(self.res_dir), "w") as xml:
+        with open(f"{self.res_dir}/results.xml", "w", encoding='utf-8') as xml:
             with subprocess.Popen(
                     ['subunit2junitxml'], stdin=subprocess.PIPE,
                     stdout=subprocess.PIPE) as stats:
@@ -69,7 +69,7 @@ class Suite(testcase.TestCase):
         Raises:
             CalledProcessError
         """
-        cmd = ['subunit2html', stream, '{}/results.html'.format(self.res_dir)]
+        cmd = ['subunit2html', stream, f'{self.res_dir}/results.html']
         output = subprocess.check_output(cmd)
         self.__logger.debug("\n%s\n\n%s", ' '.join(cmd), output)
 
@@ -117,10 +117,10 @@ class Suite(testcase.TestCase):
                 stream=stream, verbosity=2).run(self.suite).decorated
             self.generate_stats(stream)
             self.generate_xunit(stream)
-            with open('{}/subunit_stream'.format(self.res_dir), 'wb') as subfd:
+            with open(f'{self.res_dir}/subunit_stream', 'wb') as subfd:
                 stream.seek(0)
                 shutil.copyfileobj(stream, subfd)
-            self.generate_html('{}/subunit_stream'.format(self.res_dir))
+            self.generate_html(f'{self.res_dir}/subunit_stream')
             self.stop_time = time.time()
             self.details = {
                 "testsRun": result.testsRun,
index 72d54b5..c3bc432 100644 (file)
@@ -44,13 +44,13 @@ class VnfOnBoarding(testcase.TestCase):
     def __init__(self, **kwargs):
         super().__init__(**kwargs)
         self.uuid = uuid.uuid4()
-        self.user_name = "{}-{}".format(self.case_name, self.uuid)
-        self.tenant_name = "{}-{}".format(self.case_name, self.uuid)
+        self.user_name = f"{self.case_name}-{self.uuid}"
+        self.tenant_name = f"{self.case_name}-{self.uuid}"
         self.snaps_creds = {}
         self.created_object = []
         self.os_project = None
-        self.tenant_description = "Created by OPNFV Functest: {}".format(
-            self.case_name)
+        self.tenant_description = (
+            f"Created by OPNFV Functest: {self.case_name}")
 
     def run(self, **kwargs):
         """
index b206a49..e2a2712 100644 (file)
@@ -100,7 +100,7 @@ class RunTestsTesting(unittest.TestCase):
             mock_method.return_value.__iter__ = lambda self: iter(
                 self.readline, '')
             self.runner.source_envfile(envfile)
-            mock_method.assert_called_once_with(envfile, 'r')
+            mock_method.assert_called_once_with(envfile, 'r', encoding='utf-8')
             self.assertEqual(os.environ[key], value)
 
     def test_source_envfile(self):
index 7cfcdec..cd39f13 100644 (file)
@@ -119,10 +119,10 @@ class RunTesting(unittest.TestCase):
             html_file = os.path.join(self.test.res_dir, 'output.html')
             args_list = [
                 '--junit',
-                '--junit-directory={}'.format(self.test.res_dir),
-                '--format=json', '--outfile={}'.format(self.test.json_file),
+                f'--junit-directory={self.test.res_dir}',
+                '--format=json', f'--outfile={self.test.json_file}',
                 '--format=behave_html_formatter:HTMLFormatter',
-                '--outfile={}'.format(html_file),
+                f'--outfile={html_file}',
                 '--tags='+','.join(self.tags)]
             args_list.append('foo')
             args[0].assert_called_once_with(args_list)
@@ -152,10 +152,10 @@ class RunTesting(unittest.TestCase):
         html_file = os.path.join(self.test.res_dir, 'output.html')
         args_list = [
             '--junit',
-            '--junit-directory={}'.format(self.test.res_dir),
-            '--format=json', '--outfile={}'.format(self.test.json_file),
+            f'--junit-directory={self.test.res_dir}',
+            '--format=json', f'--outfile={self.test.json_file}',
             '--format=behave_html_formatter:HTMLFormatter',
-            '--outfile={}'.format(html_file),
+            f'--outfile={html_file}',
             '--tags='+','.join(self.tags)]
         if console:
             args_list += ['--format=pretty', '--outfile=-']
index 9e5e109..76ae2c1 100644 (file)
@@ -120,7 +120,7 @@ class BashFeatureTesting(FeatureTestingBase):
     def test_run_ko1(self, *args):
         with mock.patch('builtins.open', mock.mock_open()) as mopen:
             self._test_run(testcase.TestCase.EX_RUN_ERROR)
-        mopen.assert_called_once_with(self._output_file, "w")
+        mopen.assert_called_once_with(self._output_file, "w", encoding='utf-8')
         args[0].assert_called_once_with(
             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
         args[1].assert_called_once_with(self.feature.res_dir)
@@ -136,8 +136,12 @@ class BashFeatureTesting(FeatureTestingBase):
         args[0].configure_mock(**attrs)
         with mock.patch('builtins.open', mock.mock_open()) as mopen:
             self._test_run(testcase.TestCase.EX_RUN_ERROR)
-        self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
-        self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'w', encoding='utf-8'),
+            mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'r', encoding='utf-8'),
+            mopen.mock_calls)
         args[0].assert_called_once_with(
             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
         args[1].assert_called_once_with(self.feature.res_dir)
@@ -159,8 +163,12 @@ class BashFeatureTesting(FeatureTestingBase):
         args[1].configure_mock(**attrs)
         with mock.patch('builtins.open', mock.mock_open()) as mopen:
             self._test_run_max_duration(testcase.TestCase.EX_RUN_ERROR)
-        self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
-        self.assertNotIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'w', encoding='utf-8'),
+            mopen.mock_calls)
+        self.assertNotIn(
+            mock.call(self._output_file, 'r', encoding='utf-8'),
+            mopen.mock_calls)
         args[1].assert_called_once_with(
             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
         wait.assert_called_once_with(timeout=FeatureTestingBase._max_duration)
@@ -178,8 +186,12 @@ class BashFeatureTesting(FeatureTestingBase):
         args[0].configure_mock(**attrs)
         with mock.patch('builtins.open', mock.mock_open()) as mopen:
             self._test_run(testcase.TestCase.EX_OK)
-        self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
-        self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'w', encoding='utf-8'),
+            mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'r', encoding='utf-8'),
+            mopen.mock_calls)
         args[0].assert_called_once_with(
             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
         args[1].assert_called_once_with(self.feature.res_dir)
@@ -195,8 +207,12 @@ class BashFeatureTesting(FeatureTestingBase):
         args[0].configure_mock(**attrs)
         with mock.patch('builtins.open', mock.mock_open()) as mopen:
             self._test_run_console(True, testcase.TestCase.EX_OK)
-        self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
-        self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'w', encoding='utf-8'),
+            mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'r', encoding='utf-8'),
+            mopen.mock_calls)
         args[0].assert_called_once_with(
             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
         args[1].assert_called_once_with(self.feature.res_dir)
@@ -212,8 +228,12 @@ class BashFeatureTesting(FeatureTestingBase):
         args[0].configure_mock(**attrs)
         with mock.patch('builtins.open', mock.mock_open()) as mopen:
             self._test_run_console(False, testcase.TestCase.EX_OK)
-        self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
-        self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'w', encoding='utf-8'),
+            mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'r', encoding='utf-8'),
+            mopen.mock_calls)
         args[0].assert_called_once_with(
             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
         args[1].assert_called_once_with(self.feature.res_dir)
@@ -230,8 +250,12 @@ class BashFeatureTesting(FeatureTestingBase):
         args[0].configure_mock(**attrs)
         with mock.patch('builtins.open', mock.mock_open()) as mopen:
             self._test_run_console(False, testcase.TestCase.EX_OK)
-        self.assertIn(mock.call(self._output_file, 'w'), mopen.mock_calls)
-        self.assertIn(mock.call(self._output_file, 'r'), mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'w', encoding='utf-8'),
+            mopen.mock_calls)
+        self.assertIn(
+            mock.call(self._output_file, 'r', encoding='utf-8'),
+            mopen.mock_calls)
         args[0].assert_called_once_with(
             self._cmd, shell=True, stderr=mock.ANY, stdout=mock.ANY)
         args[1].assert_called_once_with(self.feature.res_dir)
index bc05f52..f36625e 100644 (file)
@@ -140,9 +140,9 @@ class GenerateReportTesting(unittest.TestCase):
         args[0].assert_called_once_with(self.test.xml_file)
         args[1].assert_called_once_with(args[0].return_value)
         args[2].assert_called_once_with(
-            report='{}/report.html'.format(self.test.res_dir),
-            log='{}/log.html'.format(self.test.res_dir),
-            xunit='{}/xunit.xml'.format(self.test.res_dir))
+            report=f'{self.test.res_dir}/report.html',
+            log=f'{self.test.res_dir}/log.html',
+            xunit=f'{self.test.res_dir}/xunit.xml')
 
     @mock.patch('robot.reporting.resultwriter.ResultWriter.write_results',
                 return_value=0)
@@ -154,9 +154,9 @@ class GenerateReportTesting(unittest.TestCase):
         args[0].assert_called_once_with(self.test.xml_file)
         args[1].assert_called_once_with(args[0].return_value)
         args[2].assert_called_once_with(
-            report='{}/report.html'.format(self.test.res_dir),
-            log='{}/log.html'.format(self.test.res_dir),
-            xunit='{}/xunit.xml'.format(self.test.res_dir))
+            report=f'{self.test.res_dir}/report.html',
+            log=f'{self.test.res_dir}/log.html',
+            xunit=f'{self.test.res_dir}/xunit.xml')
 
 
 class RunTesting(unittest.TestCase):
index 9e5f132..5cce83b 100644 (file)
@@ -54,7 +54,7 @@ class SuiteTesting(unittest.TestCase):
             ['subunit2junitxml'], stdin=subprocess.PIPE,
             stdout=subprocess.PIPE)
         mock_open.assert_called_once_with(
-            '{}/results.xml'.format(self.psrunner.res_dir), 'w')
+            f'{self.psrunner.res_dir}/results.xml', 'w', encoding='utf-8')
 
     @mock.patch('subprocess.Popen')
     def test_generate_xunit_ok(self, *args):
@@ -69,7 +69,7 @@ class SuiteTesting(unittest.TestCase):
             ['subunit2junitxml'], stdin=subprocess.PIPE,
             stdout=subprocess.PIPE)
         mock_open.assert_called_once_with(
-            '{}/results.xml'.format(self.psrunner.res_dir), 'w')
+            f'{self.psrunner.res_dir}/results.xml', 'w', encoding='utf-8')
 
     @mock.patch('subprocess.check_output', side_effect=Exception)
     def test_generate_html_ko(self, *args):
@@ -78,7 +78,7 @@ class SuiteTesting(unittest.TestCase):
             self.psrunner.generate_html(stream)
         args[0].assert_called_once_with(
             ['subunit2html', stream,
-             '{}/results.html'.format(self.psrunner.res_dir)])
+             f'{self.psrunner.res_dir}/results.html'])
 
     @mock.patch('subprocess.check_output')
     def test_generate_html_ok(self, *args):
@@ -86,7 +86,7 @@ class SuiteTesting(unittest.TestCase):
         self.psrunner.generate_html(stream)
         args[0].assert_called_once_with(
             ['subunit2html', stream,
-             '{}/results.html'.format(self.psrunner.res_dir)])
+             f'{self.psrunner.res_dir}/results.html'])
 
     @mock.patch('xtesting.core.unit.Suite.generate_html')
     @mock.patch('xtesting.core.unit.Suite.generate_xunit')
@@ -98,14 +98,14 @@ class SuiteTesting(unittest.TestCase):
         with mock.patch('builtins.open', mock.mock_open()) as m_open:
             self.assertEqual(self.psrunner.run(), status)
         m_open.assert_called_once_with(
-            '{}/subunit_stream'.format(self.psrunner.res_dir), 'wb')
+            f'{self.psrunner.res_dir}/subunit_stream', 'wb')
         self.assertEqual(self.psrunner.is_successful(), result)
         args[0].assert_called_once_with(self.psrunner.suite)
         args[1].assert_not_called()
         args[2].assert_called_once_with(mock.ANY)
         args[3].assert_called_once_with(mock.ANY)
         args[4].assert_called_once_with(
-            '{}/subunit_stream'.format(self.psrunner.res_dir))
+            f'{self.psrunner.res_dir}/subunit_stream')
 
     @mock.patch('xtesting.core.unit.Suite.generate_html')
     @mock.patch('xtesting.core.unit.Suite.generate_xunit')
@@ -117,14 +117,14 @@ class SuiteTesting(unittest.TestCase):
         with mock.patch('builtins.open', mock.mock_open()) as m_open:
             self.assertEqual(self.psrunner.run(name=name), status)
         m_open.assert_called_once_with(
-            '{}/subunit_stream'.format(self.psrunner.res_dir), 'wb')
+            f'{self.psrunner.res_dir}/subunit_stream', 'wb')
         self.assertEqual(self.psrunner.is_successful(), result)
         args[0].assert_called_once_with(self.psrunner.suite)
         args[1].assert_called_once_with()
         args[2].assert_called_once_with(mock.ANY)
         args[3].assert_called_once_with(mock.ANY)
         args[4].assert_called_once_with(
-            '{}/subunit_stream'.format(self.psrunner.res_dir))
+            f'{self.psrunner.res_dir}/subunit_stream')
 
     @mock.patch('xtesting.core.unit.Suite.generate_html')
     @mock.patch('xtesting.core.unit.Suite.generate_xunit')
index 2810df1..ae6ffa4 100644 (file)
@@ -24,8 +24,8 @@ from xtesting.utils import decorators
 __author__ = "Cedric Ollivier <cedric.ollivier@orange.com>"
 
 DIR = '/dev'
-FILE = '{}/null'.format(DIR)
-URL = 'file://{}'.format(FILE)
+FILE = f'{DIR}/null'
+URL = f'file://{FILE}'
 
 
 class FakeTestCase(testcase.TestCase):
@@ -108,7 +108,7 @@ class DecoratorsTesting(unittest.TestCase):
                                create=True) as mock_open:
             test = self._get_testcase()
             self.assertEqual(test.push_to_db(), testcase.TestCase.EX_OK)
-        mock_open.assert_called_once_with(FILE, 'a')
+        mock_open.assert_called_once_with(FILE, 'a', encoding='utf-8')
         handle = mock_open()
         call_args, _ = handle.write.call_args
         self.assertIn('POST', call_args[0])
index 2ce12fa..2de0b81 100644 (file)
@@ -30,12 +30,13 @@ def can_dump_request_to_file(method):
             except OSError as ex:
                 if ex.errno != errno.EEXIST:
                     raise
-            with open(parseresult.path, 'a') as dumpfile:
+            with open(parseresult.path, 'a', encoding='utf-8') as dumpfile:
                 headers = ""
                 for key in request.headers:
                     headers += key + " " + request.headers[key] + "\n"
-                message = "{} {}\n{}\n{}\n\n\n".format(
-                    request.method, request.url, headers, request.body)
+                message = (
+                    f"{request.method} {request.url}"
+                    f"\n{headers}\n{request.body}\n\n\n")
                 dumpfile.write(message)
         return mock.Mock()