Skip to content

[2/8] Use assert(Not)Regex instead of assertTrue or assertFalse in tests - #5241

Merged
akesandgren merged 7 commits into
easybuilders:developfrom
Flamefire:assertregex-2
Sep 14, 2026
Merged

akesandgren merged 7 commits into
easybuilders:developfrom
Flamefire:assertregex-2

Conversation

@Flamefire

Copy link
Copy Markdown
Contributor

This makes the tests shorter and hence easier to read, avoids re.compile calls and manual failure message composing. In some cases assert_multi_regex could be used to avoid the explicit loops.

… in tests

This makes the tests shorter and hence easier to read, avoids
`re.compile` calls and manual failure message composing.
In some cases `assert_multi_regex` could be used to avoid the explicit loops.
Comment thread test/framework/config.py
res = get_log_filename('foo', '1.2.3', date='19700101', timestamp='094651', add_salt=True)
regex = re.compile(os.path.join(tmpdir, r'easybuild-foo-1\.2\.3-19700101\.094651\.[a-zA-Z]{5}\.log$'))
self.assertTrue(regex.match(res), "Pattern '%s' matches '%s'" % (regex.pattern, res))
self.assertRegex(res, os.path.join(tmpdir, r'easybuild-foo-1\.2\.3-19700101\.094651\.[a-zA-Z]{5}\.log$'))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why the lack of re.compile here compared to the others above?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or perhaps the question should be why keep the re.compile above?

@Flamefire Flamefire Sep 11, 2026 •

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

re.compile was required when flags were used. E.g. when ^$ should match line begin/end. I removed the remaining ones that were no longer required now

Comment thread test/framework/module_generator.py Outdated
Comment thread test/framework/module_generator.py Outdated
for pattern in patterns:
regex = re.compile(pattern, re.M)
self.assertFalse(regex.search(desc), "Pattern '%s' not found in: %s" % (regex.pattern, desc))
self.assert_multi_regex(patterns, desc, assert_true=False)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hmmm didn't think of this in the 1/8 PR... the assert_true is a weird name, just "assert" would make more sense, at least to me. (or at least something else than assert_true...)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this existed before. How about assert_match?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

that feels better at least...

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done. Can you merge this soon so I can update the others before they fail post-merge?

Comment thread test/framework/package.py
Comment on lines 240 to +258
@@ -255,7 +255,7 @@ def test_package(self):
self.assertTrue(os.path.isfile(pkgfile))
pkgtxt = read_file(pkgfile)
self.assertRegex(pkgtxt, r"""DESCRIPTION:.*`backticks'.*""")
self.assertRegex(pkgtxt, re.compile(r"""DESCRIPTION:.*\nand newlines""", re.MULTILINE))
self.assertRegex(pkgtxt, r"""DESCRIPTION:.*\nand newlines""")

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't these two actually need MULTILINE? the first one does have a "$" in the middle of the regex at least and the second one includes newline in the pattern

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The first one? r"""DESCRIPTION:.*backticks'.*"""has no$`

MULTILINE only affects ^ and $ to match line start/end, so a \n always matches a newline

Comment thread test/framework/package.py
no_logfiles_regex = re.compile(r'STARTCONTENTS.*\.(log|md)$.*ENDCONTENTS', re.DOTALL | re.MULTILINE)
res = no_logfiles_regex.search(pkgtxt)
self.assertFalse(res, "Pattern not '%s' found in: %s" % (no_logfiles_regex.pattern, pkgtxt))
self.assertNotRegex(pkgtxt, re.compile(r'STARTCONTENTS.*\.(log|md)$.*ENDCONTENTS', re.DOTALL | re.M))

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, this is the one I meant that has $ in the middle

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok, I had kept the re.M there.

@Flamefire

Copy link
Copy Markdown
Contributor Author

I pulled in another change to assert_multi_regex from one of the other PRs to avoid changing that multiple times.
It looks like for multiple regexes we usually want the multiline feature and we had used it as such

However IMO this is not a safe default: With re.M it may have additional matches, which is ok for assert_match=False but for assert_match=True I'd say it would be better to be explicit when we need it.
Maybe we should have that as default: multi_line = not assert_match

There is at least 1 check that is supposed to match at the beginning/end of the string, not each line.
Comment thread test/framework/module_generator.py Outdated
pattern = r"\s*extensions\("

self.assertFalse(re.search(pattern, desc), "No extensions found in: %s" % desc)
self.assertNotRegex(pattern, desc, re)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Still don't understand the "re" as third argument here. The third argument is the message string to be printed if you don't want the default.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a leftover. I thought I had fixed that, done now

akesandgren
akesandgren previously approved these changes Sep 14, 2026

@akesandgren akesandgren left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@akesandgren akesandgren added this to the next release (5.4.1) milestone Sep 14, 2026

@akesandgren akesandgren left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks even better now :-)

@akesandgren

Copy link
Copy Markdown
Contributor

Going in, thanks @Flamefire!

@akesandgren
akesandgren merged commit 31da57d into easybuilders:develop Sep 14, 2026
41 checks passed
@Flamefire
Flamefire deleted the assertregex-2 branch September 14, 2026 10:28
@Flamefire

Copy link
Copy Markdown
Contributor Author

@akesandgren Followup: #5285 as per my last comment.
Can you check that soon?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants