Files
anomalyco_opencode/packages/opencode/specs/simulation-research/text/2026-evolution-python-tests-to-pbt.txt
T
2026-07-01 21:45:53 +00:00

928 lines
94 KiB
Plaintext
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
On the Evolution of Python Test Cases into
Property-based Tests
Cindy Wauters Ruben Opdebeeck Coen De Roover
Software Languages Lab Software Languages Lab Software Languages Lab
Vrije Universiteit Brussel Vrije Universiteit Brussel Vrije Universiteit Brussel
Brussels, Belgium Brussels, Belgium Brussels, Belgium
cindy.suzy.wauters@vub.be ruben.denzel.opdebeeck@vub.be coen.de.roover@vub.be
Abstract—Conventionally, unit tests exercise their unit under Scala2 , Python3 and JavaScript4 . Proposing domain-specific
test on predetermined input to validate its behavior. The advent input generation strategies and invariant properties, research
of property-based testing frameworks has led to unit tests that initiatives have brought property-based testing to challenging
exercise the unit under test on randomly-generated inputs, for
which the units behavior has to satisfy developer-specified invari- application domains such as telecom software [2], distributed
ant properties. The promise of increased coverage and stronger synchronization services [19], neural networks [33], and cyber-
validation may lead developers to evolve existing conventional physical systems [13].
unit tests into property-based ones. This paper reports on the Despite these successes, property-based tests often consti-
results of an empirical study of 257 property-based unit tests tute only a fraction of the test suite. According to a 2023
(PBT) from 64 open-source repositories that have evolved from a
conventional unit test. The study examines each PBT-introducing JetBrains survey [22], the most common PBT framework
commit for change patterns, and for the type of features of for Python, Hypothesis, was only used by 5% of Python
property-based testing frameworks that are adopted. Next, it developers. To bring the benefits of property-based testing
investigates the impact of PBT adoption by running test cases to to more projects, researchers have proposed tool support for
compute changes in code coverage and test failures. Finally, the creating property-based tests [16], [38]. However, there is a
study investigates the evolution of the newly-introduced PBT by
comparing its first to its most recent version. The studys findings gap in the research when it comes to the evolution of existing
include that 37 out of 257 evolutions required no changes to the test cases into property-based tests. Therefore, in this paper, we
body of the test. When changes are required, these are most investigate these evolutions, their impact, and the maintenance
likely to target setup code followed by oracle code. Over half of of the evolved test cases. By doing so, we aim to provide
the studied PBTs use off-the-shelf input generators, yet see an valuable insights for testers, tool builders, and researchers
improvement in code coverage by an average of 4 statements.
Additionally, for 5 test cases, the PBT found a counterexample alike. With this paper, we make the following contributions:
where the original unit test passed. Finally, 80% of the evolved • We collect a dataset of 257 test case evolutions across
test cases are still present in the current version of the project. 64 open-source GitHub repositories written in Python.
Index Terms—Empirical study, software testing, property-
based testing, code coverage Our data collection targets Python projects as, at the time
of writing, it is one of the most popular programming
I. I NTRODUCTION languages [21]. We provide a replication package [40]
Conventionally, unit tests take an example-based form in containing the resulting dataset and the implementation
which the unit under test is exercised on predetermined input. of all subsequent analyses.
For a unit test that should be run with several inputs, param- • An empirical analysis of the changes required to rewrite
eterized unit testing [35] frameworks support substituting the a conventional unit test into a property-based test, as well
example input by a parameter for which the developer provides as whether test cases evolved afterwards.
a predetermined collection of values. When enumerating these • An empirical analysis of the impact of these evolutions
input values becomes intractable, property-based testing [6] on the system under test in terms of changes in code
frameworks support generating them randomly according to coverage and test failures.
a developer-specified input generation strategy. For each of The remainder of this paper is structured as follows. Sec-
the generated inputs, the property-based test (PBT) will check tion II provides a motivating example and introduces the
that the behavior of the unit under test satisfies a developer- research questions. Section III details the dataset of real-world
specified invariant property. test evolutions we will be working with. Then, Section IV,
The QuickCheck framework [6] for the Haskell program- Section V, and Section VI present our research questions. For
ming language was the first to support property-based testing. each of the three research questions, we detail the research
Since then, more than 35 property-based testing tools [18]
have been introduced for various languages, such as Java1 , 2 https://github.com/typelevel/scalacheck
3 https://github.com/HypothesisWorks/hypothesis
1 https://github.com/jqwik-team/jqwik 4 https://github.com/dubzzz/fast-check
def test_encode_decode(): However, it can be difficult for developers to come up
txt = "hello world" with invariant properties to test [14]. The Hypothesis Quick-
assert decode(encode(txt)) == txt start [43] hints at existing parameterized unit tests (PUTs) and
existing sources of randomness in a test suite for inspiration.
Listing 1: An example-based test for encode and decode However, to our knowledge, no research has looked into real-
world test case evolutions such as the one described above. In
import pytest this paper, we answer the following research questions:
• RQ1: How do conventional unit tests evolve into
testdata = ["hello world", "test -", "(/test)"]
@pytest.mark.parametrize("txt", testdata) property-based tests? In this research question, we
def test_encode_decode(txt): investigate real-world commits for the changes required
assert decode(encode(txt)) == txt to rewrite a conventional example-based unit test or
parameterized unit test into a property-based one.
Listing 2: A parameterized unit test for encode and decode • RQ2: What is the impact of adopting property-based
testing? To investigate the impact of these test case
evolutions, we compute the difference in code coverage
method, the findings, and present an objective analysis of before and after the rewrites as well as the test failures.
these findings. Section VII discusses the actionable insights • RQ3: How are property-based tests maintained?
gained from the findings across the research questions. Here To assess the effort required to maintain the resulting
we also describe the threats to validity and their mitigation. In property-based tests, we investigate whether there are
Section VIII we position our work and compare it to current changes made to the test cases after their rewriting into
research into property-based testing. a property-based test, or if they are removed.
II. M OTIVATING E XAMPLE AND R ESEARCH Q UESTIONS III. DATASET
In order to study real-world unit test evolutions, we first
Test cases may evolve over time. To illustrate such an evo-
need a dataset of open-source repositories that contain at least
lution, consider an encode function and its inverse decode.
one property-based unit test (PBT) that started as either an
Listing 1 depicts an example-based unit test (EBT) checking
example-based unit test (EBT) or as a parameterized unit test
that decoding the encoding of "hello world" results in
(PUT). Our data collection will start from Python repositories
the same string. This unit test validates the behavior of the
that have a dependency on the Hypothesis [27] framework
unit under test for a single developer-provided example string.
for property-based testing. While other empirical studies have
Using Pytest [23], the most common Python testing frame- collected such repositories before (e.g., [32], [39]), we collect
work, the example-based unit test from Listing 1 can be gener- our own to ensure the dataset contains ample instances of test
alized into a parameterized unit test [36]. Listing 2 depicts an case evolutions.
example generalization in which a parameter txt substitutes 1) Data collection: We first use the GitHub API to find
for the earlier example input. Three possible values have been open-source Python repositories that have a dependency on
provided for the parameter, thereby validating the behavior on Hypothesis. In order to exclude toy projects, we only include
predetermined strings that contain special characters. projects that have at least three stars. We also filter out larger
Using Hypothesis [26], [27], the most popular property- projects with more than 10 stars. While these projects can
based testing framework for Python, the test case can be be valuable to study, they are also difficult for an outsider
generalized further. Listing 3 depicts the resulting property- to understand and reason about. We do not consider those
based test, specifying that the composition of decoding after projects suitable for a deep manual investigation, as required
encoding is the identity operation for all strings generated for this empirical study section. In total, we considered 1388
using st.text. Hypothesis will automatically generate mul- repositories that have a dependency on Hypothesis and satisfy
tiple strings, each of which will be encoded and decoded and our inclusion criteria.
compared to the original string. This way, the property-based Next, we use PyDriller [34] to find all PBTs in a repository
unit test might uncover defects for edge cases the developer did that were once either an EBT or a PUT, and are now a PBT.
not enumerate in the example-based nor in the parameterized To this end, we rely on the presence of @given decorators in
version of the unit test. a file with a PBT. The GitHub API alone does not suffice, as
noted by prior empirical studies into real-world Hypothesis
from hypothesis import given, strategies as st usage (e.g., [8], [32], [39]), due to the existence of other
libraries named Hypothesis. The @given decorator in a test
@given(st.text()) file, in contrast, denotes the entry point of a Hypothesis-based
def test_encode_decode(txt): PBT. If none exists, the repository does not contain a PBT, and
assert decode(encode(txt)) == txt is excluded. If we find at least one PBT in a file, we investigate
all previous versions of the file. In case the PBT exists in the
Listing 3: A property-based test for encode and decode initial commit of the file, PBTs have always existed in that
# LOC Python # evolved test cases # commits 1 def test_tolerance_sign_EBT():
Mean 7575 4.02 923 2 r = R.from_min_max(3, 2)
Std Dev. 17147 6.66 1996 3 assert r.tolerance == 0.2
4
median 2607 2 294
5
1st Quar. 1178 1 121.5 6 @given( unit=st.sampled_from((U, I, P, R)),
3rd Quar. 5346 4 680.5 7 a=st.floats(allow_nan=False),
Min 164 1 15 8 b=st.floats(allow_nan=False))
9 def test_tolerance_sign_PBT(unit, a, b):
Max 109516 39 10274
10 eu = unit.from_min_max(a, b)
assert eu.tolerance >= 0
TABLE I: Characteristics of the 64 repositories investigated 11
in this paper. Lines of Code computed by Cloc [10].
Listing 4: A real test case before and after becoming a PBT.
Some simplifications applied for readability. Case taken from
https://github.com/wese3112/eecalpy
file, and we do not consider this file relevant for investigating
test case evolution. In case there is a previous version of the
file in which the PBT did not exist, while it does in a newer
end, we categorize all changes to the body of the test case into
version, we manually investigate the last version before the
the following categories (four per type):
introduction with the first version after the introduction. We
• Changes to the oracle code: non-semantic changes, se-
perform this step manually to ensure that we also retrieve
evolutions of tests that have been renamed. Additionally, we mantic changes, additional oracles, removal of oracles.
• Changes to the setup code: non-semantic changes, se-
take note of whether the transformation in question is from an
EBT to a PBT, or from a PUT to a PBT. We recognize PUTs as mantic changes, additional setup code, removal of setup
unit tests adorned with the @pytest.mark.parametrize code.
decorator. This renders their recognition purely syntactic. To delimit test oracle code, we follow the definition of Barr
2) Characteristics of the dataset: Out of the 1388 et al. [3]. It is the part of the code that decides whether
Hypothesis-dependent GitHub repositories initially discovered, the system under test behaves as expected. This does not
575 have at least one PBT present. Upon filtering for test case necessarily mean that only (nor all) the code in an assert
evolutions, we identified 64 repositories that feature at least statement is part of the oracle code. Code that defines the
one evolution from an EBT or PUT into a PBT —amounting oracle is included too.
to 257 PBT before-after mappings. For each PBT, we have As setup code, we consider those parts of the body of
a mapping from the test before the PBT introduction to the the test case that create or retrieve values through which the
test after the PBT introduction. For a minority of PBTs, the behavior of the system under test will be validated. In other
test before its introduction was split into multiple PBTs. On words, it sets up the system under test. This is similar to the
the other hand, some tests were merged into a single PBT. In definition of a test fixture by Meszaros [28]. This is sometimes
these cases, we consider the same PBT multiple times (each also known as test context. However, we only consider the
time with a different mapping). Our 257 before-after mappings code inside the body of the test case.
therefore consist of 252 unique tests before PBT introduction As a non-semantic change to the body of a test case,
and 250 unique PBTs. Of the total 257 test case evolutions, we consider straightforward refactorings such as changing a
182 test cases follow the EBT to PBT evolution, whereas 75 constant to a value generated by the input generation strategy.
follow the PUT to PBT evolution. Table I presents summary For semantic changes, in contrast, we consider anything that
statistics of the distribution of the data across the most recent changes the semantics of a test case (e.g., extra calculations
version of the repositories. Included are the lines of code in within existing code). An addition or removal of setup code
Python (blank lines and comments not included), the number means any lines added removed, that can be considered setup
of investigated test case evolutions, and the total number of code. An addition or removal of oracle code is the addition
commits per repository. of, for example, a new assert statement, or the removal of an
old one.
IV. RQ1: H OW DO CONVENTIONAL UNIT TESTS EVOLVE A test case can evolve into a PBT through several of
INTO PROPERTY- BASED TESTS ? these types of changes. To illustrate, consider Listing 4 which
depicts one of the test cases in our dataset before and after
RQ1 investigates how PBTs can evolve out of conventional evolving into a PBT. Line 2, as well as the r.tolerance
test cases. To this end, we manually investigate the 257 afore- in line 3 is considered the setup code: these lines define
mentioned real-world before-after mappings in the dataset. what will be tested later. The assert statement, excluding
r.tolerance, is oracle code. This test case changes in two
A. Research Method
different ways. First, a non-semantic change to the setup code:
1) Changes to the test case body: First, we consider how on line 10 and 11, we see a renaming of r to eu. Additionally,
test cases are updated when they evolve into a PBT. To this hardcoded values R, 3, and 2 are replaced with the parameters
that will now be generated data. Second, a semantic change • Control: assume, @note, @event, target, used in
in the oracle code: as the values are not hardcoded anymore, the test case to modify how it is treated by the test runner,
an exact expected value is not known anymore, and the oracle or to further document it.
needs to be updated. The change from == to >= makes this a 3) Input generation strategies: As the input generation
semantic change. strategy is an important part of every PBT, we also categorize
Furthermore, it is also possible that the test case changed the strategies chosen at migration time as follows:
beyond recognition when it was rewritten into a PBT. During • Simple: strategies that generate standard values (e.g.,
our manual investigation, we mark such test cases as replaced, integers, floats, strings), and collections thereof (e.g., lists,
rather than updated, if we cannot recognize it within the PBT tuples). Strategies that compose standard values into a
anymore. Some large-scale studies into test evolution have user-defined data type are classified in the next category
used thresholds on automatically-computed similarity metrics instead.
instead (e.g., 66% used in [5] and [11]), but these make less • Custom, with reuse: strategies that are custom to the
sense when applied to small test cases instead of large files. project, but reused across multiple test cases.
We therefore rely on human judgement of the labelers instead. • Custom, no reuse: strategies that are custom to the
If the labelers cannot identify similar code in the test case project, but not reused across multiple test cases
before and after the evolution, and especially in their assert • Other: usage of third-party libraries for input generation.
statements, the test is tagged as different test cases. For example, to generate NumPy values.
The labeling was performed individually by the first and We assign each test case one of these four categories.
second authors of this paper. After a first round of labeling, Custom strategies encompass cases where developers define
we assessed inter-rater agreement using Cohens Kappa [7] their own, complex, input generators for the test cases. We also
calculated for each category, obtaining a mean Kappa of 0.475, consider any usage of builds and from_type in this cate-
signifying “moderate agreement” [25]. To avoid systematic gory, as developers use them to generate custom user-defined
disagreements, the two labelers discussed and resolved dis- data types. When a test generates both values of standard and
agreements on a random sample of 20% of the entire dataset to user-defined data types, we consider its generation strategy
establish a shared understanding. For instance, a recurring dis- custom overall.
agreement was the presence of setup code in assert statements.
After resolving these differences, the labelers individually B. Results
performed a second round of labeling on the remaining 80%, 1) Changes to the test case body: We first discuss the
resulting in a mean Kappa of 0.727, signifying “substantial changes that conventional unit tests undergo when rewritten
agreement” [25]. The remaining disagreements were discussed into a property-based test. Figure 1 shows the results for both
among the two labelers to obtain consensus. EBTs and PUTs that evolved into a PBT.
2) Features of the property-based testing framework that For test cases that evolved from EBTs in our dataset, it is
are adopted: Property-based testing frameworks often offer especially common (117/182) for the setup code to be changed
features to customize a test case. The @example decorator of in a non-semantic way (for example, replacing a hardcoded
Hypothesis, for example, enables specifying that a value needs value to instead refer to the input generation strategy, as
to be tested on every run of the test case. This can be used shown in Listing 4). The second most common change is for
with known edge cases that the developer is aware of. The the oracle code to be updated with a non-semantic change.
@settings decorator lets developers specify test budgets, Other common changes are additions of oracle code, semantic
the maximum number of examples to be generated, etc. It is changes to oracle code, and removal of oracle code or setup
also possible to reproduce test failures by re-using the random code. Additionally, 12% of cases changed beyond recognition.
input generation seed that found the counterexample (e.g., the Tests that evolve from PUTs are a bit different. Here,
input for which the property did not hold). we see fewer changes in the test cases overall. The most
We track the use of these features at the time the PBT was common change is the addition of oracle code, followed by
introduced. By doing so, we aim to discover whether devel- the addition of setup code, and semantic changes to the oracle
opers are using them from the onset. We use the following code. Notably, 35/75 test case evolutions from PUTs in our
categorization according to the Hypothesis API [42]: dataset required no change at all in the body of the test case
• Strategies: @given to generate inputs. The next para- (in comparison to 2 stemming from EBTs). Many PUTs might
graph categorizes the input strategies specified through already be testing a property, especially if they contain no
this decorator further. hardcoded expected values in the parameter. This means that
• Explicit inputs: @example, which enable the tester to evolving them into a property-based test can be less labor-
provide inputs to test each run. intensive for developers.
• Reproducing inputs: @reproduce_failure and 2) Features of the property-based testing framework that
@seed, to reproduce the data from previous test are adopted: The results are shown in Table II. All tests
failures. specified at least one input generation strategy, as expected
• Settings: @settings, to impose test budgets, a maxi- from a PBT. Hypothesis itself sees this decorator as the
mum number of examples to generate, etc. entry point of a PBT. Control (specifically assume), was
64.3% PBT origin
from example-based test
60 from parameterized test
50
Percent of tests
40
30 29.1%
22.5% 22.5%
20.0% 20.3%
20
17.6% 17.0%
16.0% 16.0%
14.7%
12.0% 12.1%
10 8.0%
6.7% 6.6% 6.7% 6.7%
0
tic
tic
tic
e
e
tic
e
dd
d
ov
as
ov
ad
an
an
an
an
:a
em
tc
em
m
em
em
em
p:
le
s
se
:r
t-u
r
c
te
s
:s
s
p:
ra
-
le
n-
Se
on
t
p:
t-u
O
le
en
c
no
t-u
ra
:n
c
Se
er
ra
O
p:
Se
le
iff
O
t-u
c
D
ra
Se
O
Fig. 1: The changes example-based (blue) and parameterized (orange) unit tests undergo when evolving into a property-based
test. Each test case can undergo multiple changes from different categories.
From EBT From PUT novice users of the framework, or because the test cases did
Feature # of test cases % # of test cases % not yet have the time to evolve and be tailored to the project.
Strategies 182 100 75 100 Therefore, we also investigate how the evolved test cases are
Explicit inputs 4 2.20 2 2.67 maintained in Section VI-B2.
Reproducing inputs 0 0 0 0 3) Input generation strategies: Table III depicts the results
Settings 11 6.04 8 10.67 for our analysis of the input generation strategies used. The
Control 2 1.10 14 18.67 majority of PBTs that evolve from an EBT have a simple input
generation strategy for standard data types. However, for 76 of
TABLE II: Features initially adopted from PBT framework. the 120 simple cases (a majority), more refined configurations
are used of these simple input generators (such as min/max
bounds for integers). 60 of the EBTs that evolved into PBTs
the second most common feature, followed by @settings now have a custom input generation, of which 24 are reused
(mostly imposing deadlines on the test cases) and explicit multiple times across different test cases.
inputs (@example). The fact that we see no PBT using When considering PBTs that have evolved from a PUT, just
failure-reproducing features is not surprising, as it is the first over half of the PBTs have a simple input generation strategy.
PBT-version of the test cases. They might not yet have run Of those 43 PBTs, 35 refined configurations. All custom input
enough to want to reproduce a specific failure-inducing input. generation strategies are reused across multiple test cases. It is
Compared to test cases that evolved from EBTs, test cases common for evolved PUTs from the same project to already
that evolved from PUTs are more likely to adopt these features share the same input parameter before their evolution into a
of the PBT framework. One reason for this could be that PBT. In our dataset, the use of libraries for input generation is
the developers are already more familiar with more advanced not common (only two instances). The only used library was
testing frameworks. the Hypothesis NumPy extension5 .
Corgozinho et al. [8] also performed a preliminary study Several test cases already contained some form of random-
into commonly used features across 86 PBTs. Their dataset ization before being rewritten into a PBT. Afterwards, this
does not consider the initial PBT introduction, and contains randomization is still reflected in the input generation strategy.
more well-established, big projects that make use of property- For example, if a test case previously contained a statement a
based testing. In their dataset, they observe a higher feature
adoption rate compared to ours. This could be because devel- 5 https://hypothesis.readthedocs.io/en/latest/reference/strategies.html#
opers evolving a PBT from an existing test might be more hypothesis-numpy
From EBT From PUT that define behavior in their test files, these should indeed
# % # % be considered. For others, including test files can lead to a
Custom, with reuse 36 19.78 32 42.67 wrong conclusion when the test cases themselves have shrunk
Custom, no reuse 24 13.19 0 0 or increased in size. We therefore report both on the absolute
Simple 120 65.94 43 57.33 and relative coverage twice, once with the test files included
Other 2 1.10 0 0 and once with the test files excluded.
We were able to run 219 of the test cases before PBT-
TABLE III: Input generation strategies used within PBTs introduction, and 219 test cases after PBT-introduction. How-
evolved from an EBT or a PUT. ever, not all were able to obtain code coverage. In the end,
we were able to run and obtain code coverage for 211 test
case evolutions before and after the introduction of the PBT
= np.random.randint(1, 10), a strategy of the test (meaning a total of 422 test cases). To ensure the test cases ran,
case would become @given(st.int(1, 10)). some minimal changes to the code were needed. For example,
one test case contained a broken import. Upon correcting this
RQ1 Non-semantic changes to the setup code are es- import, the test case did run. However, we made sure to not
pecially common in evolutions stemming from EBTs change the semantics of the system under test. In some cases,
(117/182). For evolutions from PUTs, it is more common tests failed but still resulted in some code coverage. Their
to require no changes in the body of the test case at all results are also included.
(35/75). The addition of settings is the most common
3) Test failures: Code coverage is not the only way to deter-
feature (19/257) early on in the adoption of the PBT
mine whether tests are effective. During the data collection of
framework. Most test cases use simple input generation
Section V-A2, not all test cases passed, and some test oracles
strategies (163/257).
threw an assertion error. For some test cases, this happened
before their evolution into PBT, whereas for others, the PBT
V. RQ2: W HAT IS THE IMPACT OF ADOPTING
did not pass. We investigate how often this occurs, and the
PROPERTY- BASED TESTING ?
failed assertions in each.
With research question two, we aim to find the impact
of introducing PBTs. We consider commit messages, code B. Results
coverage, and test failures of the 257 test evolutions. 1) PBT-introducing commits: First, we report on our anal-
ysis of the commit messages of the PBT-introducing commits.
A. Research Method Only eight commit messages mention anything positive or
1) PBT-introducing commits: We investigate and report on negative about Hypothesis or property-based testing (beyond
73 commit messages across 64 repositories that evolve at least simply stating that they have started using it). One commit
one conventional test case into a PBT. We aim to uncover message mentions improving code coverage to find more
reasons as to why the developer decided to evolve their test errors across the code. Two commit messages mention the new
case, and their potential opinions on this change. PBTs failing (a bug was found, but not yet fixed). Finally, five
2) Code coverage: We first explore whether code coverage commit messages use the words better, trickier, or improved.
improves once a conventional test case has evolved into a Four commit messages also mentioned bug fixes of some
PBT. Improving coverage can be a goal for some PBT- sort, meaning the PBT was introduced at the same time as a
introducing developers, even though it does not necessarily bug fix. This can indicate that the PBT at introduction might
improve test suite effectiveness [20]. Moreover, research has have found a bug that the initial conventional test case did
proposed variants of PBT with that explicit aim (i.e., coverage- not, after which the developer fixed the bug. Alternatively, the
guided PBT [24], [29], [30]). developer may also be introducing bug fixes and PBTs at the
We run each test case with statement coverage before same time to ensure their most recent bug fix is tested more
and after the introduction of Hypothesis while measuring in the future. We did not find any evidence in the commit
coverage using Coverage.py [4], a well-established Python message supporting either hypothesis, but Section V-B3 looks
library for test coverage. We only compute the coverage for into test case failures before and after the commit.
each individual test case, instead of for the entire test suite as a 2) Code coverage: To verify whether there is a difference
whole. For relative coverage (i.e., in percentage), we normalize in coverage before and after the evolution into PBT, we use a
the executed statements by those in the files executed by the Wilcoxon signed-rank test [41] as our data is non-parametric
test case rather than by those in the entire project. We opted and paired (code coverage of a test case before and after the
for this design as coverage across all statements of the entire PBT-introducing commit). We consider a p-value of <0.05
project would be very low for individual test cases. We also statistically significant. The test results are listed in Table IV.
report on coverage in absolute numbers. This can be useful For all 4 cases, we observe a statistically significant difference.
for test cases that lead to the execution of several files. Note First, we look at the change in number of statements
that, by default, coverage.py considers all executed Python covered. Figure 2 shows box plots for the distribution of the
files including the files that define the test case. For projects absolute statement coverage before and after the test case
Stmt (all) % (all) Stmt (no test) % (no test) coverage ∆ # Stmt (all) % (all) # Stmt (no test) % (no test)
p-value 0.006 2.497 × 1020 1.477 × 1013 0.045 Mean +13.09 +2.31 +4.01 -0.82
Std Dev. 27.79 6.06 16.81 5.5
TABLE IV: p-values of change in coverage, in terms of
median +11 +0.57 +0 +0
absolute and relative statement coverage.
1st Quar. +2 -0.06 +0 -1.26
total # ran tests # passing # failing with coverage 3rd Quar. +17 +2.46 +3 +0.28
Before PBT 219 199 20 211 Min -78 -10.09 -75 -21.90
After PBT 219 207 12 211 Max +223 +32.61 +77 +32.52
TABLE V: Number of passing and failing test cases. We could TABLE VI: Changes in code coverage, both in terms of
not obtain coverage for all tests (as shown by the last column). number of statements covered and change in the coverage
percentage, for both all files and all files without test files
included.
2500
evolution, taking into account all executed files (denoted “all”
in the plot) and all executed files without test files (denoted
2000 “no test”). While we see a slight improvement in median
and quartiles when all executed files are taken into account,
1500
the change becomes much more subtle when excluding the
executed test files. One reason could be that property-based
test cases execute more lines of test code. Even if the tests
1000
themselves are not necessarily longer, the inclusion of input
generators can add more test code to cover —especially for
500 projects that have defined custom ones in test files.
Figure 3 on the other hand shows the relative statement
coverage in percentage. As mentioned before, by default,
0
coverage.py only takes into consideration files that have at
Before (all) After (all) Before (no test) After (no test)
least one executed line of code, meaning files that are never
covered by the test case are not considered. Here we also see
an improvement when taking into account test files, but once
Fig. 2: Statements covered by test cases before and after PBT-
they are removed from the data, we notice a slight decrease
introduction. The first two plots show coverage across all files,
in code coverage on average.
the second two without test files included.
Table VI shows the deltas for each of the four measure-
ments. While the mean absolute number of covered statements
without test files included does improve slightly (4.01), the
relative coverage percentage goes down slightly. This could
100 be due to extra files being discovered, or more code being
introduced during the PBT-introducing commit. Most notice-
80 ably, one projects covered statements decreases by 75. Upon
further investigation, the test case in question contained many
assert statements. While the conventional test case before
60
PBT-introduction passed, Hypothesis found a counterexample
on the first assert, thereby stopping the test case and not
40 executing the subsequent assert statements (leading to a drastic
decrease in coverage). Additionally, 26 test cases from the
same repository all had one additional change when evolved
20
into PBT: the removal of a call to the logging function (which
was three statements), leading to a decrease of coverage of
0 indeed 3 statements for these 26 test cases.
Before % (all) After % (all) Before % (no test) After % (no test) 3) Test failures: Table V shows the number of tests failed
before and after PBT-introduction. Two test cases did not pass
as a conventional unit test, nor after having been rewritten into
Fig. 3: Coverage percentage by test cases before and after a PBT. For 18 test cases, the initial conventional test did not
PBT-introduction. The first two plots show coverage across pass, but the updated PBT did pass. In another ten cases, the
all files, the second two without test files included. initial test passed but the resulting PBT did not.
In terms of the before, one project with one evolution • Updates to the test case encompassing both semantic and
had a test case that resulted in an assertion error. The PBT- non-semantic changes.
introducing commit also contained a bug fix. Another project We make one exception for 39 test cases originating from
had three failing test cases that returned a type error. After the one repository. In the most recent version of that repository,
introduction of the PBT, all three passed. However, the PBT- most Python code has been removed, and is scheduled to be
introducing commit does not introduce a bug fix (meaning added at a later stage. Because of this drastic rewrite affecting
the bug was in the test code itself). Another project had two the latest version in the repository, we instead consider its most
failing test cases, with an attribute error and a type error. For recent version with the test cases still present.
both, the PBT versions did pass. In one of the bigger projects Additionally, we report on the survival rate of the test cases
in our dataset, with 16 evolved test cases, ten tests did not by looking at the number of commits since introduction, or
pass before the evolution. In three cases this was because of the number of commits between introduction and removal.
an assertion error (with the other seven not passing due to a 2) Are more parts of the PBT framework adopted?: As de-
value not being defined). All ten of these test cases passed after velopers become more acquainted with property-based testing
being updated to a PBT. These results suggest that people are in their projects, they might discover features unbeknownst
introducing PBTs when fixing known errors, perhaps to ensure to them before. Therefore, similar to Section IV-A2, we
more thorough testing of those parts of the system. investigate whether the most recent version of their PBT
When looking at the failing tests cases after the introduction uses more features of the PBT framework. We use the same
of PBTs, we found five test cases for which Hypothesis categories of features from the Hypothesis API [42] to classify
reported a counterexample for which the original test case the additions. As all PBTs already had an input generation
passed. Further, as mentioned in Section V-B1, some commits strategy when they were introduced, we investigate whether
did contain additional bug fixes. This indicates that PBTs can this strategy has been updated in the meantime.
uncover bugs not found by conventional test cases validating
the same behavior, thus improving bug detection. For the B. Results
other 5 non-passing PBTs, we found other errors (such as 1) Do Property-based Test Cases Change?: To answer this
ValueErrors), even though the original test case passed before. question, we compare the most recent commit in the GitHub
repository to the PBT-introducing commit. Table VII shows
RQ2 8 PBT-introducing commit messages convey an the number of commits the test cases have survived (for those
intent to improve test cases to improve coverage or find that are still present in the current version of their project,
bugs. We observed a statistically significant change in i.e., the number of commits between introduction and the
statement coverage, with on average an increase of 4 most current commit), or how many repository commits they
statements. We also found evidence of PBTs being intro- survived before their deletion. Most test cases in our dataset
duced along with a fix for a bug in the code, and of PBTs (110) are unchanged. Their corresponding repositories have
finding counterexamples where the original corresponding also enjoyed the fewest commits since the PBT-introducing
conventional test passed. one (with 99 on average, with a standard deviation of 205).
Interestingly, one test case survived 1728 repository commits
VI. RQ3: H OW ARE PROPERTY- BASED TESTS without undergoing any changes itself. A total of 90 test cases
MAINTAINED ?
did undergo changes since their introduction, both semantics-
We consider the most recent version of the 250 unique PBTs preserving and semantics-affecting ones. We observe that these
from the in total 257 test case evolutions, and investigate the test cases also survived more commits, with on average 642
changes (or removals) they have been subject to since. commits and a higher standard deviation. This is expected as
PBTs need to co-evolve with their system under test.
A. Research Method
Finally, 50 PBTs were removed from the projects since
For each test case, we compare the version resulting from their initial introduction. These test cases also survived fewer
the PBT-introducing commit to the version in the most recent commits; 352 on average. However, one test case survived
commit in its repository. We consider the following: 3573 commits to the repository before being removed. Reasons
1) Do Property-based Test Cases Change?: We investigate cited for the deletion of these test cases were removal of the
whether the 250 PBTs in our dataset change over time, for functions they tested (5), unexpected behavior (3), and the tests
instance in response to changes in the system under test. For being slow (1).
each PBT, we manually compare against the same test case in 2) Are more parts of the PBT framework adopted?: Finally,
the most recent version of the GitHub repository. For each of we consider the changes made to PBTs in terms of the parts of
our test cases, we consider the following: the PBT framework that are adopted. Table VIII describes the
• No changes to the test case. The rest of the project and results. In 65 test cases, the input generation strategies were
other test cases might have changed, but the investigated updated after their introduction. One repository in particular
PBT has not. mentions doing so to improve the running time of the test
• Removal of the test case. In this case, we also investigate cases. Only one repository added an explicit input to test for on
possible reasons why. each run. Additionally, one test case added a seed decorator
No changes Changes Removal easier to evolve unit tests that exercise the unit under test on
Mean 99 642 352 inputs of standard data types (e.g., integers) into a PBT with
Std Dev. 205.31 1450.79 967.80 such a strategy. Our findings should motivate practitioners to
median 51 146 34 prioritize their generalization efforts on those unit tests first.
1st Quar. 48 64 17 Finally, a study by Goldstein et al. [14] reports that PBT
3rd Quar. 63 146 71 adopters have difficulty identifying the properties to test for.
Min 1 17 7 Using existing test cases, rather than creating new ones, might
Max 1728 5886 3573
help. This is especially true for parameterized unit tests (PUT),
and especially those that do not list expected outputs for every
TABLE VII: Number of commits since the introduction of the given input, as those might already be testing a property (but
PBT. Data split for the test cases that did not change at all, for not yet randomly generating input). Indeed, for 35/75 PBTs
those with changes, and for those removed in the meantime. that evolved from a PUT (Section IV-B), no changes to the
body of the test case were required at all. This suggests that
Feature # of test cases PUTs can be considered a stepping stone towards, or even an
Change in strategies 65 intermediate step in a planned introduction of PBTs.
Addition of explicit inputs 1 For tool developers: Recent years have seen the introduc-
Addition of reproducing inputs 1 tion of tool support for creating PBTs. From Hypothesis
Addition of settings 19 own ghostwriter6 , over using LLMs to write PBTs [13], [38],
Addition of control 0 to tools that aim to aggregate similar test cases into one
Addition of exceptions 0 PBT [31]. Tools that take EBTs and transform them into PUTs
also exist [37]. However, there remains a need for tools that
TABLE VIII: Changes in used PBT features in the most recent support developers in evolving existing, dissimilar, test cases
versus the initial PBT-introducing commit of the test case. into PBTs. Our findings for RQ1 (Section IV-B), and our
supporting dataset, can inspire tool builders with examples of
to reproduce inputs. 19 of the test cases eventually got some real-world transformations that can be partially automated.
form of settings added, which doubles their total number. As shown in Section IV-B2, not all features of the property-
based testing framework are immediately adopted in newly-
RQ3 Most PBTs (200/250) in our dataset have survived evolved PBTs. In Section VI-B2 we found that features such
since their introduction, with 90 having gone through as PBT settings are often included only later in the life of
changes. Removed test cases survived on average 352 a PBT. We also saw that inside some PBTs, developers were
commits to the repository. 65 test cases saw a change using if-statements, where an assume might have been more
in their input generation strategy since their introduction. appropriate. Therefore, future tools could not only help with
Finally, 19 test cases received additional settings. the evolution of test cases into PBTs, but also aid with the
introduction of features to optimize existing PBTs.
VII. D ISCUSSION For researchers: There are still few empirical work that
We now distil the actionable insights from our findings, for compares conventional unit tests to PBTs. Ours is, to our
software testers, tool builders, and researchers alike. We also knowledge, the first to do so in a one-to-one comparison of test
discuss the threats to the validity of our findings. cases before and after their evolution into property-based ones.
Our comparison on test failures and code coverage has been
A. Actionable insights insightful, and could inspire other one-to-one comparisons on
For software testers: As evidenced by our findings for other metrics. For instance, mutation score (recently used in
RQ2 (Section V-B), evolving well-chosen unit tests into prior work [32], see Section VIII) has not yet been explored
property-based ones can increase their code coverage. We in a one-to-one comparative setting.
moreover found evidence of such real-world evolutions finding
B. Threats to validity
counterexamples where the original test passed without any
failures, leading to a deeper validation of the system under Following standard practice in empirical software engineer-
test. We even found instances of these evolutions being con- ing, we discuss potential threats to the validity of our results.
ducted alongside bug fixes, most likely to test for regressions For each threat, we describe the applied mitigation strategies.
more thoroughly. Our findings should motivate practitioners Construct validity: We considered test case evolutions that
to consider unit tests that have missed edge cases in the past are found in open-source GitHub repositories, which can
as candidates to be evolved into property-based ones. raise quality concerns. We mitigated this threat by applying
Prior studies have found that implementing input generation strict inclusion criteria, resulting in 575 high-quality candidate
strategies for a PBT can be tedious and effort-intensive [14]. repositories with at least one PBT. As most of those PBTs did
Nonetheless, our findings for RQ1 (Section IV-B) indicate not result from an evolution, we were left with fewer test case
that many evolved PBTs in our dataset use but a simple, 6 https://hypothesis.readthedocs.io/en/latest/reference/integrations.html#
built-in input generation strategy. Practitioners may find it ghostwriter
evolutions to study, but the study subjects still stem from 64 Goldstein et al. [14] interviewed 30 developers from a
different repositories, ensuring diversity. fintech company, to find insights about how people experience
Further, while false negatives cannot be excluded, all test PBT in practice. Another paper by Goldstein et al. [15] reports
case evolutions were manually inspected by both the first that developers experience difficulties in finding properties to
and the second author, ensuring the dataset is free of false test for. Our research looks at open-source projects rather than
positives. The same goes for the before-after mappings for the industry, and investigates existing test cases.
each test case evolution, which were created by the first author A study by Wauters and De Roover [39] looked into the use
and inspected and confirmed by the second author. of PBTs by 28 open-source machine learning projects. The
Manual labeling of test case evolutions was also used to study investigated common positive and negative sentiments
answer RQ1. We mitigated the threat of subjective bias by expressed in GitHub commits and code comments, which
having multiple labelers and multiple labeling rounds until parts of a project were tested, as well as the complexity of
a substantial inter-rater agreement was reached. To answer data generation strategies. Our study also investigates data
RQ2, we used tools to execute test cases and compute their generation strategies but does not focus on ML-intensive
code coverage. To mitigate the threat of measurement bias projects that often require more complex data.
introduced by the tooling, we only used mature open-source Ravi and Coblenz [32] recently performed a large-scale
tools that are well-established within the community. empirical study on PBTs in 426 Python programs. Their study
Internal validity: For RQ2, we measure changes in code uses a data flow analysis to automatically categorize real-world
coverage induced by the evolution into a PBT. However, the PBTs into 12 categories. Additionally, they used mutation
introduction of a PBT is not always the only change in a testing to investigate how many mutations a projects existing
commit. If additional changes are present, the total number PBTs can find compared to the projects existing conventional
of statements may change, which can confound the observed tests. Our research looks at the impact of evolving test cases,
coverage differences and lead to incorrect conclusions. To and compares a test case before its evolution into a PBT to
mitigate this threat, we manually inspected commits exhibiting the resulting PBT. This means we compare two test cases that
large coverage changes. In addition, we report both absolute are equivalent in terms of the behavior they are supposed to
and relative coverage, computed with and without the test files validate, and we do so one-to-one.
included, as test files are more likely to change due to the Unlike our study, the aforementioned papers do not inves-
introduction of PBTs. tigate the evolution of PBTs, but rather consider snapshots of
External validity: Finally, our study focuses on Python PBTs at one point in time.
test cases that use the Hypothesis framework. Hypothesis IX. C ONCLUSION AND F UTURE W ORK
is the most widely recognized PBT framework for Python, This paper studied the evolution of property-based unit tests
and Python is ranked among the most popular programming from conventional ones, the impact of such PBT-introducing
languages. Nevertheless, our findings may not generalize to evolutions, and how the resulting PBTs are maintained after-
other programming languages nor to other PBT frameworks. wards. We found that the evolution of parameterized unit tests
into a PBT commonly requires no updates to their test body
VIII. R ELATED W ORK
at all. For example-driven unit tests, in contrast, the evolution
Several studies have investigated the introduction and main- commonly required non-semantic changes to the test body.
tenance of various types of test cases, from tests in general [1], These account for the introduction and usage of a randomly
[9], [44] over GUI tests [5] to performance tests [11]. A generated input value. The input generation strategy of PBTs
few studies have also looked into changes in code coverage that evolved from existing unit tests is often simple. Impact-
induced by software patches, e.g., [12] and [17]. However, wise, we found that code coverage can improve when unit tests
our work is the first to study how PBTs can evolve from are replaced by PBTs. More importantly, we found evidence
conventional unit tests, and to study the impact on code of bugs found through or alongside the introduction of these
coverage —rather than changes in code coverage over time PBTs. Most of the PBTs in our dataset are still present in the
or induced by changes to the system under test. most recent version, with almost half having gone through
Zooming in on other studies targeting property-based test- some maintenance during their life time. The adoption of
ing, Corgozinho et al. [8] sampled 86 PBTs from GitHub, and additional PBT features is not uncommon either.
categorized each of them manually according to the testing One avenue for future work is investigating the long-term
patterns they adhere to, which stem from an influential blog impact of PBT-introducing test case evolutions. Another is
post7 . They also study the use of Hypothesis features in developer support in the form of a tool that identifies candidate
those PBTs, similar to us. However, while they investigate unit tests for such an evolution, and for partially automating
bigger, established projects, we investigate the adoption of the necessary test changes.
these features in test cases that were previously not a PBT.
ACKNOWLEDGEMENTS
We also study whether those features are adopted later on,
while the PBT matures. This research was partially funded by the Research Foun-
dation Flanders (FWO) Grant No. 1SHFI24N and by the
7 https://fsharpforfunandprofit.com/posts/property-based-testing-2/ Cybersecurity Research Program Flanders (CRPF).
R EFERENCES [18] John Hughes. Experiences with QuickCheck: Testing the Hard Stuff and
Staying Sane, pages 169186. Springer International Publishing, Cham,
[1] Maurı́cio Aniche, Christoph Treude, and Andy Zaidman. How develop- 2016.
ers engineer test cases: An observational study. IEEE Transactions on [19] John Hughes, Benjamin C. Pierce, Thomas Arts, and Ulf Norell. Myster-
Software Engineering, 48(12):49254946, 2022. ies of dropbox: Property-based testing of a distributed synchronization
[2] Thomas Arts, John Hughes, Joakim Johansson, and Ulf Wiger. Testing service. In 2016 IEEE International Conference on Software Testing,
telecoms software with quviq quickcheck. In Proceedings of the 2006 Verification and Validation (ICST), pages 135145, 2016.
ACM SIGPLAN Workshop on Erlang, ERLANG 06, page 210, New [20] Laura Inozemtseva and Reid Holmes. Coverage is not strongly correlated
York, NY, USA, 2006. Association for Computing Machinery. with test suite effectiveness. In Proceedings of the 36th International
[3] Earl T. Barr, Mark Harman, Phil McMinn, Muzammil Shahbaz, and Conference on Software Engineering, ICSE 2014, page 435445, New
Shin Yoo. The oracle problem in software testing: A survey. IEEE York, NY, USA, 2014. Association for Computing Machinery.
Transactions on Software Engineering, 41(5):507525, 2015. [21] Paul Jansen. Tiobe index for december 2025. https://web.archive.org/
web/20251218235222/https://www.tiobe.com/tiobe-index/. Accessed on
[4] Ned Batchelder and Contributors to Coverage.py. Coverage.py: The code
20 december 2025.
coverage tool for Python. https://web.archive.org/web/20251223093400/
[22] JetBrains. Python developers survey 2023 results. https:
https://github.com/coveragepy/coveragepy. Accessed on 20 december
//web.archive.org/web/20250920050020/https://lp.jetbrains.com/
2025.
python-developers-survey-2023/. Accessed on 10 december 2025.
[5] Laurent Christophe, Reinout Stevens, Coen De Roover, and Wolfgang
[23] Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris
De Meuter. Prevalence and maintenance of automated functional tests for
Bruynooghe, Brianna Laugher, and Florian Bruhin. pytest
web applications. In 2014 IEEE International Conference on Software
9.0.0. https://web.archive.org/web/20250906051102/https:
Maintenance and Evolution, pages 141150, 2014.
//github.com/pytest-dev/pytest/, 2004. Version 9.0.0 Contributors
[6] Koen Claessen and John Hughes. Quickcheck: a lightweight tool
include Holger Krekel, Bruno Oliveira, Ronny Pfannschmidt, Floris
for random testing of haskell programs. In Proceedings of the Fifth
Bruynooghe, Brianna Laugher, Florian Bruhin, and others.
ACM SIGPLAN International Conference on Functional Programming,
[24] Leonidas Lampropoulos, Michael Hicks, and Benjamin C. Pierce. Cov-
ICFP 00, page 268279, New York, NY, USA, 2000. Association for
erage guided, property based testing. Proc. ACM Program. Lang.,
Computing Machinery.
3(OOPSLA), October 2019.
[7] Jacob Cohen. A coefficient of agreement for nominal scales. Educational [25] J. Richard Landis and Gary G. Koch. The measurement of observer
and psychological measurement, 20(1):3746, 1960. agreement for categorical data. Biometrics, 33(1):159174, 1977.
[8] Arthur Lisboa Corgozinho, Marco Tulio Valente, and Henrique Rocha. [26] David R. MacIver and Alastair F. Donaldson. Test-Case Reduction via
How Developers Implement Property-Based Tests . In 2023 IEEE Inter- Test-Case Generation: Insights from the Hypothesis Reducer. In Robert
national Conference on Software Maintenance and Evolution (ICSME), Hirschfeld and Tobias Pape, editors, 34th European Conference on
pages 380384, Los Alamitos, CA, USA, October 2023. IEEE Computer Object-Oriented Programming (ECOOP 2020), volume 166 of Leibniz
Society. International Proceedings in Informatics (LIPIcs), pages 13:113:27,
[9] Ermira Daka and Gordon Fraser. A survey on unit testing practices and Dagstuhl, Germany, 2020. Schloss Dagstuhl Leibniz-Zentrum für
problems. In 2014 IEEE 25th International Symposium on Software Informatik.
Reliability Engineering, pages 201211, 2014. [27] David R MacIver, Zac Hatfield-Dodds, et al. Hypothesis: A new
[10] Albert Danial. cloc: v1.92. https://doi.org/10.5281/zenodo.5760077, approach to property-based testing. Journal of Open Source Software,
December 2021. 4(43):1891, 2019.
[11] Sergio Di Meglio, Luigi Libero Lucio Starace, Valeria Pontillo, Ruben [28] Gerard Meszaros. xUnit test patterns: Refactoring test code. Pearson
Opdebeeck, Coen De Roover, and Sergio Di Martino. Performance Education, 2007.
testing in open-source web projects: Adoption, maintenance, and a [29] Agustı́n Mista and Alejandro Russo. Mutagen: Reliable coverage-
change taxonomy. In Proceedings of the 41st IEEE International guided, property-based testing using exhaustive mutations. In 2023 IEEE
Conference on Software Maintenance and Evolution (ICSME 2025). Conference on Software Testing, Verification and Validation (ICST),
IEEE, sep 2025. 41st IEEE International Conference on Software pages 176187, 2023.
Maintenance and Evolution (ICSME 2025), ICMSE ; Conference date: [30] Rohan Padhye, Caroline Lemieux, and Koushik Sen. Jqf: coverage-
07-09-2025 Through 12-09-2025. guided property-based testing in java. In Proceedings of the 28th ACM
[12] S. Elbaum, D. Gable, and G. Rothermel. The impact of software SIGSOFT International Symposium on Software Testing and Analysis,
evolution on code coverage information. In Proceedings IEEE Inter- ISSTA 2019, page 398401, New York, NY, USA, 2019. Association
national Conference on Software Maintenance. ICSM 2001, pages 170 for Computing Machinery.
179, 2001. [31] Hila Peleg, Dan Rasin, and Eran Yahav. Generating tests by example.
[13] Khashayar Etemadi, Marjan Sirjani, Mahshid Helali Moghadam, Per In Isil Dillig and Jens Palsberg, editors, Verification, Model Checking,
Strandberg, and Paul Pettersson. Llm-based property-based test genera- and Abstract Interpretation, pages 406429, Cham, 2018. Springer
tion for guardrailing cyber-physical systems. In International Conference International Publishing.
on Bridging the Gap between AI and Reality, pages 1846. Springer [32] Savitha Ravi and Michael Coblenz. An empirical evaluation of property-
Nature Switzerland Cham, 2025. based testing in python. Proc. ACM Program. Lang., 9(OOPSLA2),
[14] Harrison Goldstein, Joseph W. Cutler, Daniel Dickstein, Benjamin C. October 2025.
Pierce, and Andrew Head. Property-based testing in practice. In Pro- [33] Mohammad Rezaalipour and Carlo A. Furia. An annotation-based
ceedings of the IEEE/ACM 46th International Conference on Software approach for finding bugs in neural network programs. Journal of
Engineering, ICSE 24, New York, NY, USA, 2024. Association for Systems and Software, 201:111669, 2023.
Computing Machinery. [34] Davide Spadini, Maurı́cio Aniche, and Alberto Bacchelli. Pydriller:
[15] Harrison Goldstein, Joseph W Cutler, Adam Stein, Benjamin C Pierce, Python framework for mining software repositories. In Proceedings of
and Andrew Head. Some problems with properties. In Proc. Workshop the 2018 26th ACM Joint Meeting on European Software Engineering
on the Human Aspects of Types and Reasoning Assistants (HATRA), Conference and Symposium on the Foundations of Software Engineering,
2022. ESEC/FSE 2018, page 908911, New York, NY, USA, 2018. Associa-
[16] Harrison Goldstein, Jeffrey Tao, Zac Hatfield-Dodds, Benjamin C. tion for Computing Machinery.
Pierce, and Andrew Head. Tyche: Making sense of pbt effectiveness. In [35] Nikolai Tillmann and Wolfram Schulte. Parameterized unit tests.
Proceedings of the 37th Annual ACM Symposium on User Interface SIGSOFT Softw. Eng. Notes, 30(5):253262, September 2005.
Software and Technology, UIST 24, New York, NY, USA, 2024. [36] Nikolai Tillmann and Wolfram Schulte. Parameterized unit tests. In
Association for Computing Machinery. Proceedings of the 10th European Software Engineering Conference
[17] Michael Hilton, Jonathan Bell, and Darko Marinov. A large-scale study Held Jointly with 13th ACM SIGSOFT International Symposium on
of test coverage evolution. In Proceedings of the 33rd ACM/IEEE Foundations of Software Engineering, ESEC/FSE-13, page 253262,
International Conference on Automated Software Engineering, ASE 18, New York, NY, USA, 2005. Association for Computing Machinery.
page 5363, New York, NY, USA, 2018. Association for Computing [37] Deepika Tiwari, Yogya Gamage, Martin Monperrus, and Benoit Baudry.
Machinery. Proze: Generating parameterized unit tests informed by runtime data.
In 2024 IEEE International Conference on Source Code Analysis and tation. https://web.archive.org/web/20251223092313/https://hypothesis.
Manipulation (SCAM), pages 166176, 2024. readthedocs.io/en/latest/reference/api.html. Accessed on 10 december
[38] Vasudev Vikram, Caroline Lemieux, Joshua Sunshine, and Rohan Pad- 2025.
hye. Can large language models write good property-based tests?, 2024. [43] Hypothesis Works. When to use hypothesis and property-based testing
[39] Cindy Wauters and Coen De Roover. Property-based Testing within ML - hypothesis 6.148.3 documentation. https://web.archive.org/web/
Projects: an Empirical Study . In 2024 IEEE International Conference 20251223092910/https://hypothesis.readthedocs.io/en/latest/tutorial/
on Software Maintenance and Evolution (ICSME), pages 648653, Los introduction.html#when-to-use-hypothesis-and-property-based-testing.
Alamitos, CA, USA, October 2024. IEEE Computer Society. Accessed on 11 december 2025.
[40] Cindy Wauters, Ruben Opdebeeck, and Coen De Roover. Replication [44] Andy Zaidman, Bart Van Rompaey, Serge Demeyer, and Arie van
package on the evolution of python test cases into property-based tests. Deursen. Mining software repositories to study co-evolution of pro-
https://doi.org/10.6084/m9.figshare.31424447, Feb 2026. duction & test code. In 2008 1st International Conference on Software
[41] Frank Wilcoxon. Individual comparisons by ranking methods. Biomet- Testing, Verification, and Validation, pages 220229, 2008.
rics Bulletin, 1(6):8083, 1945.
[42] Hypothesis Works. Api reference - hypothesis 6.148.3 documen-