# Tensor form factors of the octet hyperons in QCD

A. Kucukarslan1 , U. Ozdem1 , A. Ozpineci2

1 Physics Department, Canakkale Onsekiz Mart University, 17100 Canakkale,
Turkey
2 Physics Department, Middle East Technical University, 06531 Ankara, Turkey
e-mail<EMAIL_ADDRESS><EMAIL_ADDRESS>(Corresponding
author)e-mail<EMAIL_ADDRESS>
###### Abstract

Light-cone QCD sum rules to leading order in QCD are used to investigate the
tensor form factors of the $\Sigma-\Sigma$, $\Xi-\Xi$ and $\Sigma-\Lambda$
transitions in the range $1~{}GeV^{2}\leq Q^{2}\leq 10$ $GeV^{2}$. The DAs of
$\Sigma$, $\Xi$ and $\Lambda$ baryon have been calculated without higher-order
terms. Then, studies including higher-order corrections have been done for the
$\Sigma$ and $\Lambda$ baryon. The resulting form factors are obtained using
these two DAs. We make a comparison with the predictions of the chiral quark
soliton model.

Keywords— Tensor form factors, Octet-octet hyperon transitions, Light cone QCD
sum rules

##  1 Introduction

How the hadrons are built from quarks and gluons, the fundamental degrees of
freedom of QCD, is one of the main open questions in the theory of strong
interactions. An efficient way to probe the hadron structure is to study the
hadron form factors as these quantities include direct information about the
hadron structure. Therefore, the form factors have recently received
considerable attention both in theory and experiment. Like other form factors,
the tensor form factors encode the important information about the quark-gluon
structure of baryons.

The quark distributions in the leading twist are given by the unpolarized
distribution $f_{1}(x)$, helicty distribution $g_{1}(x)$ and transversity
distribution $h_{1}(x)$ function of the quark. One of these functions, the
transversity distribution -which describes the probability of finding a
transversely polarized quark with longitudinal momentum fraction $x$ in a
transversely polarized baryons [1] by its chiral-odd nature- is not easy to
measure. The strong interactions have approximate chiral symmetry and
electroweak interactions conserve the chirality, so the transversity
distributions cannot be extracted in inclusive deep inelastic scattering
(DIS). It needs to couple to another chiral-odd quantity in the cross-section.
It can be obtained Drell-Yan processes and semi-inclusive deep inelastic
scattering (SIDIS), because distributions of transversity do come out at
leading twist in the cross-section. In Ref.[2], it was extracted using the
experimental data on azimuthal asymmetries in SIDIS, from BELLE [3] as well as
data for the nucleon from the HERMES [4] and COMPASS [5] collaborations.
Subsequently, in Ref.[6], isovector nucleon tensor charge obtained
$H_{T}(0)=0.65^{+0.30}_{-0.23}$ at a renormalization scale
$\mu^{2}=0.4~{}GeV^{2}$. In Ref.[7] Anselmino et al. updated their nucleon
isovector tensor charge result $H_{T}(0)=0.77^{+0.18}_{-0.38}$ at
renormalization scale of $\mu^{2}=0.8~{}GeV^{2}$. On the theoretical side,
isovector tensor charge of the nucleon has been studied in the framework of
lattice QCD [8, 9, 10], the chiral quark soliton model $(\chi$QSM) [11, 12],
quark model [13, 14], Skyrme model [15], axial vector dominance model [16] and
dihadron production [17] QCD sum rules and light cone QCD sum rules [18, 19,
20, 21]. For octet hyperon isovector tensor transition form factors have been
studied chiral quark soliton model $(\chi$QSM) [12].

The hyperon sector is interesting because it provides for an ideal system in
which to study $SU(3)$ flavor symmetry breaking by replacing up or down quarks
in nucleons with strange ones [22]. Tensor form factors play an important role
in our understanding of the “tomography” of baryons. The hyperon tensor form
factors a missing part of the this tomography. In the present work, we
calculate the isovector tensor transition form factors of the $\Xi-\Xi$,
$\Sigma-\Sigma$ and $\Sigma-\Lambda$. In order to study the tensor form
factors, one needs to use a nonperturbative method. One of the most powerful
nonperturbative methods is traditional QCD sum rules (QCDSR), which is more
reliable and predictive in calculating the properties of hadrons [23, 24, 25,
26]. An alternative to the traditional QCD sum rules is the light cone QCD sum
rules (LCSR) [27, 28, 29]. In this method, the hadronic properties are
expressed with regards to the properties of the vacuum and the light cone
distribution amplitudes of the hadrons in the process. Since the form factors
are expressed with regards to the properties of the QCD vacuum and the
distribution amplitudes, any uncertainty in these parameters reflects to the
uncertainty of the predictions of the form factors.

Our aim in this work is to study the tensor form factors in the framework of
light-cone QCD sum rules for the octet hyperon. We give the formulation of the
hyperon form factors on the light cone and derive our sum rules. In the last
section, we present our numerical analysis and discussion.

##  2 Formalism

The matrix element of the tensor current between two hyperon states is
parametrized by three form factors as presented [30, 9]

$\displaystyle\langle H(p^{\prime})|j_{\mu\nu}|H(p)\rangle$ $\displaystyle=$
$\displaystyle\bar{u}(p^{\prime})\left[i\sigma_{\mu\nu}H_{T}(q^{2})+\frac{\gamma_{\mu}q_{\nu}-\gamma_{\nu}q_{\mu}}{2m_{H}}E_{T}(q^{2})+\frac{\tilde{P}_{\mu}q_{\nu}-\tilde{P}_{\nu}q_{\mu}}{2m_{H}^{2}}\tilde{H}_{T}(q^{2})\right]u(p),$
(1)

where $H$ = $\Sigma$, $\Xi$ and $\Lambda$ baryons and
$j_{\mu\nu}=\bar{u}i\sigma_{\mu\nu}u-\bar{d}i\sigma_{\mu\nu}d$ is the tensor
current, $\tilde{P}=p^{\prime}+p$, $q=p^{\prime}-p$ and
$\sigma_{\mu\nu}=\frac{i}{2}[\gamma_{\mu},\gamma_{\nu}]$ are the spin
operator, and $u(p)$ is the spinor of the hyperon with mass $m_{H}$ and
momentum p.

In order to calculate three tensor form factors within LCSR, we start our
analysis with the following correlation function:

$\Pi_{\mu\nu}(p,q)=i\int d^{4}xe^{iqx}\langle
0|T[j_{H}(0)j_{\mu\nu}(x)]|H(p)\rangle,$ (2)

where $J_{H}(0)$ are the hyperon interpolating fields for the $\Sigma$ and
$\Xi$. In this work, we choose the general form of the interpolating fields
for $\Sigma$ and $\Xi$ as

$\displaystyle j_{\Sigma}$ $\displaystyle=$ $\displaystyle
2\epsilon^{abc}\sum_{\ell=1}^{2}(u^{aT}(x)CJ_{1}^{\ell}s^{b}(x))J_{2}^{\ell}u^{c}(x)$
$\displaystyle J_{\Xi}$ $\displaystyle=$ $\displaystyle
J_{\Sigma}(u\leftrightarrow s)$ (3)

where $J_{1}^{1}=I$, $J_{1}^{2}=J_{2}^{1}=\gamma_{5}$ and $J_{2}^{2}=t$, which
is an arbitrary parameter. Choosing $t=-1$ makes the interpolating fields,
which are known as Ioffe currents. $a$, $b$, $c$ are the color indices and $C$
is the charge conjugation operator. Besides, the u, d, s-quark fields are
presented as $u(x)$, $d(x)$ and $s(x)$, respectively.

In order to calculate sum rules for the tensor form factors, we need to
represent the correlation function in two different forms, the first one is
calculated in terms of quark and gluon degrees of freedom, and the second one
is obtained using hadrons and the related correlation function that is written
in terms of a dispersion relation. Then, these two forms of correlation
functions are equated. In order to suppress the higher states and continuum
contributions, we also apply the Borel transformation.

The hadronic side of the correlation function can be determined as follows,

$\Pi_{\mu\nu}(p,q)=\displaystyle\sum_{p{{}^{\prime}}}\frac{\langle
0|J_{H}|{H(p^{\prime})}\rangle\langle{H(p^{\prime})}|J_{\mu\nu}|H(p)\rangle}{m^{2}_{H}-p^{\prime
2}}+...$ (4)

where $m_{H}$ are the $\Sigma$, $\Xi$ and $\Lambda$ baryon mass and dots
represents contributions from higher states and continuum. The matrix element
of the interpolating current is between the vacuum and hyperon states, defined
as

$\langle
0|J_{H}(0)|{H(p^{\prime})}\rangle=\lambda_{H}u(p^{\prime},s^{\prime})$ (5)

where $\lambda_{H}$ is the hyperon overlap amplitude. Inserting the matrix
element of the tensor current in Eq. (1) and the matrix element of the
interpolating current in Eq. (5) into the correlation function in Eq. (4), we
get

$\displaystyle\Pi_{\mu\nu}(p,q)$ $\displaystyle=$
$\displaystyle\frac{\lambda_{H}}{{m^{2}_{H}-p^{\prime
2}}}(p\\!\\!\\!/^{\prime}+m_{H})\left[i\sigma_{\mu\nu}H_{T}(q^{2})+\frac{\gamma_{\mu}q_{\nu}-\gamma_{\nu}q_{\mu}}{2m_{H}}E_{T}(q^{2})+\frac{\tilde{P}_{\mu}q_{\nu}-\tilde{P}_{\nu}q_{\mu}}{2m_{H}^{2}}\tilde{H}_{T}(q^{2})\right].$
(6)

Also, the correlation function is determined in terms of the quark and gluon
on the QCD side. The interpolating fields in Eq. (2) are inserted into the
correlation function in Eq. (2).
We obtain for $\Sigma-\Sigma$, $\Lambda-\Sigma$ and $\Xi-\Xi$ transitions,

$\displaystyle\Pi_{\mu\nu}$ $\displaystyle=$ $\displaystyle\frac{i}{2}\int
d^{4}xe^{iqx}\sum^{2}_{\ell=1}(CJ_{1}^{\ell})_{\alpha\beta}(J_{2}^{\ell})_{\gamma\delta}(\sigma_{\mu\nu})_{\omega\rho}[\delta_{\sigma}^{\delta}\delta_{\theta}^{\rho}\delta_{\phi}^{\beta}S(-x)_{\alpha\omega}+\delta_{\sigma}^{\alpha}\delta_{\theta}^{\rho}\delta_{\phi}^{\beta}S(-x)_{\delta\omega}]$
(7) $\displaystyle 4\epsilon^{abc}\langle
0|q_{1\sigma}^{a}(0)q_{2\theta}^{b}(x)q_{3\phi}^{c}(0)|H(p)\rangle$

where $q_{i}$ ($i=1,~{}2,~{}3$) denotes the quark fields, and $S(x)$
represents the quark propagator which is given as

$\displaystyle S_{q}(x)$ $\displaystyle=$
$\displaystyle\frac{ix\\!\\!\\!/}{2\pi^{2}x^{4}}-\frac{\langle
q\bar{q}\rangle}{12}\left(1+\frac{m_{0}^{2}x^{2}}{16}\right)-ig_{s}\int^{1}_{0}d\upsilon\left[\frac{x\\!\\!\\!/}{16\pi^{2}x^{4}}G_{\mu\nu}\sigma^{\mu\nu}-\upsilon
x^{\mu}G_{\mu\nu}\gamma^{\nu}\ \frac{i}{4\pi^{2}x^{2}}\right],$ (8)

In this expression, $\langle q\bar{q}\rangle$ is the quark condensate, $m_{0}$
is defined in terms of the mixed quark gluon condensate as
$\langle\bar{q}g_{s}G^{\mu\nu}\sigma_{\mu\nu}q\rangle\equiv
m_{0}^{2}\langle\bar{q}q\rangle$ and $g_{s}$ is the strong coupling constant.
$G_{\mu\nu}$ is the gluon field strength tensor. The terms proportional to
$G_{\mu\nu}$ are expected to give negligibly small contributions as they are
related to four and five-particle distribution amplitudes [31], and hence we
will get neglect these terms in further analysis. Moreover, the terms
proportional to $\langle q\bar{q}\rangle$ are removed by Borel transformations
and, finally only the first term, which gives the hard-quark propagator, will
be considered for our discussion. Then, we need to know matrix elements of the
local three-quark operator,

$\displaystyle 4\epsilon^{abc}\langle
0|q_{1\sigma}^{a}(a_{1}x)q_{2\theta}^{b}(a_{2}x)q_{3\phi}^{c}(a_{3}x)|H(p)\rangle$

where $a_{1}$, $a_{2}$ and $a_{3}$ are real numbers. This matrix element can
be written in terms of distribution amplitudes (DAs) using the Lorentz
covariance, the spin and the parity of the baryon [32]

$\displaystyle 4\epsilon^{abc}\langle
0|q_{1\sigma}^{a}(a_{1}x)q_{2\theta}^{b}(a_{2}x)q_{3\phi}^{c}(a_{3}x)|H(p)\rangle$
$\displaystyle={\cal
S}_{1}MC_{\sigma\theta}\left(\gamma_{5}H\right)_{\phi}+{\cal
S}_{2}M^{2}C_{\sigma\theta}\left(\\!\not\\!{x}\gamma_{5}H\right)_{\phi}+{\cal
P}_{1}M\left(\gamma_{5}C\right)_{\sigma\theta}H_{\phi}+{\cal
P}_{2}M^{2}\left(\gamma_{5}C\right)_{\sigma\theta}\left(\\!\not\\!{x}H\right)_{\phi}$
$\displaystyle+{\cal
V}_{1}\left(\\!\not\\!{P}C\right)_{\sigma\theta}\left(\gamma_{5}H\right)_{\phi}+{\cal
V}_{2}M\left(\\!\not\\!{P}C\right)_{\sigma\theta}\left(\\!\not\\!{x}\gamma_{5}H\right)_{\phi}+{\cal
V}_{3}M\left(\gamma_{\mu}C\right)_{\sigma\theta}\left(\gamma^{\mu}\gamma_{5}H\right)_{\phi}$
$\displaystyle+{\cal
V}_{4}M^{2}\left(\\!\not\\!{x}C\right)_{\sigma\theta}\left(\gamma_{5}H\right)_{\phi}+{\cal
V}_{5}M^{2}\left(\gamma_{\mu}C\right)_{\sigma\theta}\left(i\sigma^{\mu\nu}x_{\nu}\gamma_{5}H\right)_{\phi}+{\cal
V}_{6}M^{3}\left(\\!\not\\!{x}C\right)_{\sigma\theta}\left(\\!\not\\!{x}\gamma_{5}H\right)_{\phi}$
$\displaystyle+{\cal
A}_{1}\left(\\!\not\\!{P}\gamma_{5}C\right)_{\sigma\theta}H_{\phi}+{\cal
A}_{2}M\left(\\!\not\\!{P}\gamma_{5}C\right)_{\sigma\theta}\left(\\!\not\\!{x}H\right)_{\phi}+{\cal
A}_{3}M\left(\gamma_{\mu}\gamma_{5}C\right)_{\sigma\theta}\left(\gamma^{\mu}H\right)_{\phi}$
$\displaystyle+{\cal
A}_{4}M^{2}\left(\\!\not\\!{x}\gamma_{5}C\right)_{\sigma\theta}H_{\phi}+{\cal
A}_{5}M^{2}\left(\gamma_{\mu}\gamma_{5}C\right)_{\sigma\theta}\left(i\sigma^{\mu\nu}x_{\nu}H\right)_{\phi}+{\cal
A}_{6}M^{3}\left(\\!\not\\!{x}\gamma_{5}C\right)_{\sigma\theta}\left(\\!\not\\!{x}H\right)_{\phi}$
$\displaystyle+{\cal
T}_{1}\left(P^{\nu}i\sigma_{\mu\nu}C\right)_{\sigma\theta}\left(\gamma^{\mu}\gamma_{5}H\right)_{\phi}+{\cal
T}_{2}M\left(x^{\mu}P^{\nu}i\sigma_{\mu\nu}C\right)_{\sigma\theta}\left(\gamma_{5}H\right)_{\phi}$
$\displaystyle+{\cal
T}_{3}M\left(\sigma_{\mu\nu}C\right)_{\sigma\theta}\left(\sigma^{\mu\nu}\gamma_{5}H\right)_{\phi}+{\cal
T}_{4}M\left(P^{\nu}\sigma_{\mu\nu}C\right)_{\sigma\theta}\left(\sigma^{\mu\varrho}x_{\varrho}\gamma_{5}H\right)_{\phi}$
$\displaystyle+{\cal
T}_{5}M^{2}\left(x^{\nu}i\sigma_{\mu\nu}C\right)_{\sigma\theta}\left(\gamma^{\mu}\gamma_{5}H\right)_{\phi}+{\cal
T}_{6}M^{2}\left(x^{\mu}P^{\nu}i\sigma_{\mu\nu}C\right)_{\sigma\theta}\left(\\!\not\\!{x}\gamma_{5}H\right)_{\phi}$
$\displaystyle+{\cal
T}_{7}M^{2}\left(\sigma_{\mu\nu}C\right)_{\sigma\theta}\left(\sigma^{\mu\nu}\\!\not\\!{x}\gamma_{5}H\right)_{\phi}+{\cal
T}_{8}M^{3}\left(x^{\nu}\sigma_{\mu\nu}C\right)_{\sigma\theta}\left(\sigma^{\mu\varrho}x_{\varrho}\gamma_{5}H\right)_{\phi}\,,$
(9)

where $H_{\phi}$ is the spinor of the baryon, M is the mass of the baryon, $C$
is the charge conjugation matrix, and
$\sigma_{\mu\nu}=\frac{i}{2}[\gamma_{\mu},\gamma_{\nu}]$. The “calligraphic”
expressions can be expressed in terms of functions of the definite twist:

$\displaystyle\mathcal{S}_{1}=$ $\displaystyle S_{1},\hskip
99.58464pt2px\mathcal{S}_{2}=S_{1}-S_{2},$ $\displaystyle\mathcal{P}_{1}=$
$\displaystyle P_{1},\hskip 99.58464pt2px\mathcal{P}_{2}=P_{1}-P_{2}$
$\displaystyle\mathcal{V}_{1}=$ $\displaystyle V_{1},\hskip
99.58464pt2px\mathcal{V}_{2}=V_{1}-V_{2}-V_{3},$ $\displaystyle
2\mathcal{V}_{3}=$ $\displaystyle V_{3},\hskip
99.58464pt4px\mathcal{V}_{4}=-2V_{1}+V_{3}+V_{4}+2V_{5},$ $\displaystyle
4px\mathcal{V}_{5}=$ $\displaystyle V_{4}-V_{3},\hskip
71.13188pt4(px)^{2}\mathcal{V}_{6}=-V_{1}+V_{2}+V_{3}+V_{4}+V_{5}-V_{6}$
$\displaystyle\mathcal{A}_{1}=$ $\displaystyle A_{1},\hskip
99.58464pt2px\mathcal{A}_{2}=-A_{1}+A_{2}-A_{3},$ $\displaystyle
2\mathcal{A}_{3}=$ $\displaystyle A_{3},\hskip
99.58464pt4px\mathcal{A}_{4}=-2A_{1}-A_{3}-A_{4}+2A_{5},$ $\displaystyle
4px\mathcal{A}_{5}=$ $\displaystyle A_{3}-A_{4},\hskip
71.13188pt4(px)^{2}\mathcal{A}_{6}=A_{1}-A_{2}+A_{3}+A_{4}-A_{5}+A_{6}$
$\displaystyle\mathcal{T}_{1}=$ $\displaystyle T_{1},\hskip
99.58464pt2px\mathcal{T}_{2}=T_{1}+T_{2}-2T_{3},$ $\displaystyle
2\mathcal{T}_{3}=$ $\displaystyle T_{7},\hskip
99.58464pt2px\mathcal{T}_{4}=T_{1}-T_{2}-2T_{7},$ $\displaystyle
2px\mathcal{T}_{5}=$ $\displaystyle-T_{1}+T_{5}+2T_{8},\hskip
28.45274pt4(px)^{2}\mathcal{T}_{6}=2T_{2}-2T_{3}-2T_{4}+2T_{5}+2T_{7}+2T_{8},$
$\displaystyle 4px\mathcal{T}_{7}=$ $\displaystyle T_{7}-T_{8},\hskip
71.13188pt4(px)^{2}\mathcal{T}_{8}=-T_{1}+T_{2}+T_{5}-T_{6}+2T_{7}+2T_{8}$

where $S_{i},P_{i},V_{i},A_{i}$ and $T_{i}$ are scalar, pesudoscalar, vector,
axialvector and tensor DAs, respectively. The expansion of the matrix element
is basically an expansion in increasing twists of the DAs. The twist of a DA
is defined as the dimension minus the spin of the operators contributing to a
given DA. The DAs $A_{1}$, $T_{1}$ and $V_{1}$ have twist three, $V_{2}$,
$V_{3}$, $A_{2}$, $A_{3}$, $T_{2}$, $T_{3}$, $T_{7}$, $S_{1}$ and $P_{1}$ have
twist 4, $S_{2}$, $P_{2}$, $V_{4}$, $V_{5}$, $A_{4}$, $A_{5}$, $T_{4}$,
$T_{5}$ and $T_{8}$ are of twist 5, and $V_{6}$, $A_{6}$ and $T_{6}$ have
twist 6. The DAs $F=S_{i},P_{i},V_{i},A_{i},T_{i}$ can be written as

$F(a_{i}px)=\int
dx_{1}dx_{2}dx_{3}~{}\delta{(x_{1}+x_{2}+x_{3}-1)}~{}exp{\bigg{(}-ipx\sum_{i}{x_{i}a_{i}}\bigg{)}}~{}F(x_{i})$
(10)

where $x_{i}$ with $i=1,2,3$ corresponds to longitudinal momentum fractions
carried by the quarks inside the baryon. The explicit form of the hyperon DAs
($S_{i},P_{i},V_{i},A_{i},T_{i}$) is studied in detail in Refs. [33, 34, 35,
36]. The DAs of the octet hyperons up to twist-6 are investigated the basis of
the QCD conformal partial wave expansion approach. For the $\Sigma$ and
$\Lambda$ baryons calculations are carried out to the next-to-leading order
[34, 35, 36] and for the $\Xi$ baryon this calculation is carried out to the
leading order of conformal spin accuracy [33]. The nonperturbative parameters
(e.g. shape parameters of DAs) are obtained using the QCD sum rules [33, 34,
35, 36].

Note that the hadronic representation, Eq. (6), and the QCD representation are
obtained in different kinematical regions. The two expression can be related
to each other by using the spectral representation of the correlation
functions. Quite generally, the coefficients of various structures in the
correlation function can be written as:

$\displaystyle\Pi(p^{2},{p^{\prime}}^{2};Q^{2})=\int_{0}^{\infty}ds_{1}ds_{2}\frac{\rho(s_{1},s_{2};Q^{2})}{(s_{1}-p^{2})(s_{2}-{p^{\prime}}^{2})}+\mbox{polynomials
in $p^{2}$ or ${p^{\prime}}^{2}$}$ (11)

where $\rho$ is called the spectral density. The spectral density can be
calculated both using the hadronic representation of the correlation function,
$\rho^{h}$, or using the QCD representation, $\rho^{QCD}$. Once $\rho$ is
obtained, the spectral representation allows one to evaluate the correlation
function in all kinematical regions for $p^{2}$ and ${p^{\prime}}^{2}$.

The LCSR are obtained by matching the expression of the correlation function
in terms of QCD parameters to its expression in terms of the hadronic
properties, using their spectral representation. In order to do this, we
choose the structures proportional to structures $q\\!\\!\\!/\sigma_{\mu\nu}$,
$q_{\mu}\gamma_{\nu}-\gamma_{\mu}q_{\nu}$ and $q_{\mu}p_{\nu}q\\!\\!\\!/$ for
the form factors $H_{T}$, $E_{T}$ and $\tilde{H}_{T}$, respectively. Choosing
the coefficients of these structures and applying the Borel transformation
with respect to the variable $p^{\prime 2}=(p+q)^{2}$ we obtain tensor form
factors for $\Sigma-\Sigma$ transition,

$\displaystyle H_{T}(q^{2})\frac{\lambda_{\Sigma}}{{M_{\Sigma}^{2}-p^{\prime
2}}}$ $\displaystyle=$
$\displaystyle\int_{0}^{1}dx_{2}\frac{M_{\Sigma}}{(q-px_{2})^{2}}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}P_{1}+T_{1}-T_{2}+T_{7}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle-2\int_{0}^{1}d_{\beta}\frac{M_{\Sigma}^{3}}{(q-p\beta)^{4}}\int_{0}^{\beta}d\alpha\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}T_{1}-T_{2}-T_{5}+T_{6}-2T_{7}-2T_{8}\bigg{]}$
$\displaystyle(x_{1},x_{2},1-x_{1}-x_{2})$ $\displaystyle
E_{T}(q^{2})\frac{\lambda_{\Sigma}}{{M^{2}_{\Sigma}-p^{\prime 2}}}$
$\displaystyle=$ $\displaystyle
2\int_{0}^{1}dx_{2}\frac{M_{\Sigma}}{(q-px_{2})^{2}}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}-S_{1}+P_{1}+2T_{1}-T_{3}-T_{7}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle-2\int_{0}^{1}d_{\beta}\frac{M_{\Sigma}^{3}}{(q-p\beta)^{4}}\int_{0}^{\beta}d\alpha\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}T_{1}-T_{2}-T_{5}+T_{6}-2T_{7}-2T_{8}\bigg{]}$
$\displaystyle(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle\tilde{H}_{T}(q^{2})\frac{\lambda_{\Sigma}}{{M^{2}_{\Sigma}-p^{\prime
2}}}$ $\displaystyle=$
$\displaystyle-4M_{\Sigma}^{3}\int_{0}^{1}d\alpha\frac{1-\alpha}{(q-p\alpha)^{4}}\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}T_{1}-T_{3}-T_{7}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
(12)

for $\Sigma-\Lambda$ transition

$\displaystyle H_{T}(q^{2})\frac{\lambda_{\Sigma}}{{M_{\Lambda}^{2}-p^{\prime
2}}}$ $\displaystyle=$
$\displaystyle\int_{0}^{1}dx_{2}\frac{M_{\Lambda}}{(q-px_{2})^{2}}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}P_{1}+T_{1}-T_{2}+T_{7}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle-2\int_{0}^{1}d_{\beta}\frac{M_{\Lambda}^{3}}{(q-p\beta)^{4}}\int_{0}^{\beta}d\alpha\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}T_{1}-T_{2}-T_{5}+T_{6}-2T_{7}-2T_{8}\bigg{]}$
$\displaystyle(x_{1},x_{2},1-x_{1}-x_{2})$ $\displaystyle
E_{T}(q^{2})\frac{\lambda_{\Sigma}}{{M^{2}_{\Lambda}-p^{\prime 2}}}$
$\displaystyle=$ $\displaystyle
2\int_{0}^{1}dx_{2}\frac{M_{\Lambda}}{(q-px_{2})^{2}}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}-S_{1}+P_{1}+2T_{1}-T_{3}-T_{7}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle-2\int_{0}^{1}d_{\beta}\frac{M_{\Lambda}^{3}}{(q-p\beta)^{4}}\int_{0}^{\beta}d\alpha\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}T_{1}-T_{2}-T_{5}+T_{6}-2T_{7}-2T_{8}\bigg{]}$
$\displaystyle(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle\tilde{H}_{T}(q^{2})\frac{\lambda_{\Sigma}}{{M^{2}_{\Lambda}-p^{\prime
2}}}$ $\displaystyle=$
$\displaystyle-4M_{\Lambda}^{3}\int_{0}^{1}d\alpha\frac{1-\alpha}{(q-p\alpha)^{4}}\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}T_{1}-T_{3}-T_{7}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
(13)

for $\Xi-\Xi$ transition,

$\displaystyle H_{T}(q^{2})\frac{\lambda_{\Xi}}{{m^{2}_{\Xi}-p^{\prime 2}}}$
$\displaystyle=$
$\displaystyle\int_{0}^{1}dx_{2}\frac{M_{\Xi}}{(q-px_{2})^{2}}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}-V_{1}-V_{3}+A_{1}-A_{3}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle+2\int_{0}^{1}d_{\beta}\frac{M_{\Xi}^{3}}{(q-p\beta)^{4}}\int_{0}^{\beta}d\alpha\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}V_{1}-V_{2}-V_{3}-V_{4}-V_{5}+V_{6}-A_{1}+A_{2}$
$\displaystyle-A_{3}-A_{4}+A_{5}-A_{6}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle E_{T}(q^{2})\frac{\lambda_{\Xi}}{{m^{2}_{\Xi}-p^{\prime 2}}}$
$\displaystyle=$ $\displaystyle
4M_{\Xi}\int_{0}^{1}dx_{2}\frac{1-x_{2}}{(q-px_{2})^{2}}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}A_{1}-A_{2}-V_{1}+V_{2}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle+\int_{0}^{1}d_{\beta}\frac{M_{\Xi}^{3}}{(q-p\beta)^{4}}\int_{0}^{\beta}d\alpha\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}V_{1}-V_{2}-V_{3}-V_{4}-V_{5}+V_{6}-A_{1}$
$\displaystyle+A_{2}-A_{3}-A_{4}+A_{5}-A_{6}\bigg{]}(x_{1},x_{2},1-x_{1}-x_{2})$
$\displaystyle\tilde{H}_{T}(q^{2})\frac{\lambda_{\Xi}}{{M^{2}_{\Xi}-p^{\prime
2}}}$ $\displaystyle=$ $\displaystyle
4M_{\Xi}^{3}\int_{0}^{1}d\alpha\frac{1-\alpha}{(q-p\alpha)^{4}}\int_{\alpha}^{1}dx_{2}\int_{0}^{1-x_{2}}dx_{1}\bigg{[}V_{1}-V_{2}-V_{3}-A_{1}+A_{2}-A_{3}\bigg{]}$
(14) $\displaystyle(x_{1},x_{2},1-x_{1}-x_{2})$

In order to eliminate the subtraction terms in the spectral representation of
the correlation function, we perform to the Borel transformation. After the
transformation, contributions coming from excited and continuum states are
also exponentially suppressed. Clearly, the Borel transformation and the
subtraction of higher states are achieved by using the following substitution
rules (see e.g. [32, 37]):

$\displaystyle\int
dx\frac{\rho(x)}{(q-xp)^{2}}\rightarrow-\int_{x_{0}}^{1}\frac{dx}{x}\rho(x)e^{-s(x)/M^{2}},$
$\displaystyle\int
dx\frac{\rho(x)}{(q-xp)^{4}}\rightarrow\frac{1}{M^{2}}\int_{x_{0}}^{1}\frac{dx}{x^{2}}\rho(x)e^{-s(x)/M^{2}}+\frac{\rho(x_{0})}{Q^{2}+x_{0}^{2}m_{H}^{2}}e^{-s_{0}/M^{2}},$

where,

$\displaystyle s(x)=(1-x)m_{H}^{2}+\frac{1-x}{x}Q^{2},$ (16)

$M$ is the Borel mass and $x_{0}$ is the solution of the quadratic equation
for $s=s_{0}$:

$\displaystyle
x_{0}=\frac{\sqrt{(Q^{2}+s_{0}-m_{H}^{2})^{2}+4m_{H}^{2}Q^{2}}-(Q^{2}+s_{0}-m_{H}^{2})}{2m_{H}^{2}},$
(17)

where $s_{0}$ is the continuum threshold.

##  3 Results and Discussion

In this section, we present the numerical results of the octet-octet hyperon
isovector tensor transition form factors. In this work, we use the hyperon DAs
which depend on various nonperturbative parameters such as, $f_{\Sigma}$,
$f_{\Xi}$ and $f_{\Lambda}$ [33, 34, 35, 36]. The DAs of the $\Sigma$, $\Xi$
and $\Lambda$ baryons have been calculated by employing the QCD sum rules
without higher-order terms in Ref. [33, 34]. Then the study including higher-
order corrections have been done for $\Sigma$ and $\Lambda$ baryon in Ref.
[35, 36]. In Table 1, we present the values of the input parameters using the
DAs of $\Sigma$, $\Xi$ and $\Lambda$ baryons. For the numerical analysis, we
use the values of the hyperon masses as follow; $M_{\Lambda}=1.11~{}GeV$,
$M_{\Sigma}=1.2~{}GeV$, $M_{\Xi}=1.3~{}GeV$ [38]. Besides, we need also
specify the values of the residues of , $\Sigma$ and $\Xi$ baryon. The
residues can be determined from the mass sum rules as
$\lambda_{\Sigma}=0.039~{}GeV^{3}$ and $\lambda_{\Xi}=0.040~{}GeV^{3}$ for
$\Sigma$ and $\Xi$, respectively [39].

DAs Parameters
---
$~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}\Sigma$ | $~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}\Lambda$ | $~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}~{}\Xi$
$f=(9.4\pm 0.4)\times 10^{-3}$ GeV2 | $f=(6.0\pm 0.3)\times 10^{-3}~{}GeV^{2}$ | $f=(9.9\pm 0.4)\times 10^{-3}~{}GeV^{2}$
$\lambda_{1}=(-2.5\pm 0.1)\times 10^{-2}$ GeV2 | $\lambda_{1}=(1.0\pm 0.3)\times 10^{-2}~{}GeV^{2}$ | $\lambda_{1}=(-2.8\pm 0.1)\times 10^{-2}~{}GeV^{2}$
$\lambda_{2}=(4.4\pm 0.1)\times 10^{-2}$ GeV2 | $\lambda_{2}=(0.83\pm 0.05)\times 10^{-2}~{}GeV^{2}$ | $\lambda_{2}=(5.2\pm 0.2)10^{-2}\times~{}GeV^{2}$
$\lambda_{3}=(2.0\pm 0.1)\times 10^{-2}$ GeV2 | $\lambda_{3}=(0.83\pm 0.05)\times 10^{-2}~{}GeV^{2}$ | $\lambda_{3}=(01.7\pm 0.1)\times 10^{-2}~{}GeV^{2}$
$V_{1}^{s}=0.39\pm 0.01$ | $A_{1}^{s}=0.31\pm 0.01$ |
$A_{1}^{u}=0.29\pm 0.12$ | $A_{1}^{q}=0.032\pm 0.006$ |
$f_{1}^{s}=-0.15\pm 0.12$ | $f_{1}^{s}=0.23\pm 0.01$ |
$f_{2}^{s}=9.9\pm 2.5$ | $f_{1}^{q}=-0.23\pm 0.03$ |
$f_{3}^{s}=1.6\pm 0.2$ | $f_{3}^{q}=0.43\pm 0.07$ |
$f_{1}^{u}=-0.11\pm 0.01$ | $f_{4}^{q}=1.07\pm 0.12$ |
$P_{2}^{0}=0.004\pm 0.0004$ |  |
$S_{1}^{u}=-0.0014\pm 0.0002$ |  |
Table 1: The values of the parameters are used in the DAs of $\Sigma$,
$\Lambda$ and $\Xi$.

In the traditional analysis of sum rules, the spectral density of the higher
states and the continuum are parameterized using quark hadron duality. In this
approach, the spectral density corresponding to the contributions of the
higher states and continuum is parameterized as

$\rho^{h}(s)=\rho^{QCD}(s)\theta(s-s_{0}).$

The predictions for the form factors depend on two auxiliary parameters: the
squared of Borel mass $M^{2}$, and the continuum threshold $s_{0}$. The
continuum threshold signals the scale at which, the excited states and
continuum start to contribute to the correlation function. Hence it is
expected that $s_{0}\simeq(m_{\Sigma}+0.3)^{2}~{}GeV^{2}=2.25~{}GeV^{2}$,
$s_{0}\simeq(m_{\Lambda}+0.3)^{2}~{}GeV^{2}\simeq 1.99~{}GeV^{2}$ and
$s_{0}\simeq(m_{\Xi}+0.3)^{2}~{}GeV^{2}=2.56~{}GeV^{2}$. One approach to
determine the continuum threshold and the working region of the Borel
parameter $M^{2}$ is to plot the dependence of the predictions on $M^{2}$ for
a range of values of the continuum threshold and determine the values of
$s_{0}$ for which there is a stable region with respect to variations of the
Borel parameter $M^{2}$. For this reason, in Figs.(1)-(3), we plot the
dependence of the form factors on $M^{2}$ for fixed values of $Q^{2}$ and
various values of $s_{0}$ in the region $2~{}GeV^{2}\leq s_{0}\leq
4~{}GeV^{2}$. As can be seen from figures (in the case of old DAs and new
DAs), for $s_{0}=2.5\pm 0.5~{}GeV^{2}$, the results are practically
independent of the value of $M^{2}$ for the shown range. The uncertainty due
to variations of $s_{0}$ in this range is much larger than the uncertainty due
to variations with respect to $M^{2}$. Note that the determined range of
$s_{0}$ is in the range that one would expect from the physical interpretation
of $s_{0}$.

In Figs. (4)-(6), we present the $Q^{2}$ dependence of the form factors
obtained using two DAs. Our observations can be summarized as follows;

  1. 1.

$\Sigma-\Sigma$ case:

We show the behaviour of the form factors that agree well with our
expectations. The values of the tensor form factors decrease quickly as we
increase the momentum transfer. In Fig. (4-a, c and e) are represent the
results of the new DAs and Fig. (4-b, d and f) are represent the results of
old DAs. In both case, the $Q^{2}$ dependence of the form factors are similar
but the values of the new DAs results are larger than old DAs results. We see
that higher-order terms gives dominant contribution.

  2. 2.

$\Sigma-\Lambda$ case:

In Fig. (5-a, c and e) are represent the results of the new DAs and Fig. (5-b,
d and f) are represent the results of old DAs. In the case of old DAs, the
results of the form factors $E_{T}^{\Sigma\Lambda}$ in negatif region but new
DAs result change the behaviour this form factor. In the case of
$H_{T}^{\Sigma\Lambda}$, the $Q^{2}$ dependence of the form factor is similar
behaviour and stable but the values of the new DAs results are larger than old
one. In the case of old DAs, the results of the form factor
$\tilde{H}_{T}^{\Sigma\Lambda}$ in positive region but new DAs result change
the behaviour this form factor.

  3. 3.

$\Xi-\Xi$ case

The higher-order terms of DAs of $\Xi$ baryon have not yet been calculated. So
there is only one DAs result showing the behavior of the form factors that
agree well with our expectations. The values of the tensor form factors
decrease quickly as we increase the momentum transfers.

Unlike other form factors the tensor form factors are renormalization-scale
dependent [18]. The numerical values of DAs are used at the scale $\mu^{2}=1$
$GeV^{2}$ in Ref. [40], therefore, in present work our predictions correspond
to this scale. In order to compare our results, we use the following
expressions [41]:

$F(\mu^{2})=\left(\alpha_{s}(\mu^{2})\over\alpha_{s}(\mu_{i}^{2})\right)^{\frac{4}{33-2n_{f}}}\left[1-\frac{337}{468\pi}[\alpha_{s}(\mu_{i}^{2})-\alpha_{s}(\mu^{2})]\right]F(\mu_{i}^{2}),$
(18)

where $n_{f}$ is the number of flavors, $\mu_{i}$ is the initial
renormalization scale and

$\displaystyle\alpha_{s}(\mu^{2})=\frac{4\pi}{9\ln(\mu^{2}/\Lambda^{2})}\left[1-\frac{64}{81}\frac{\ln(\ln(\mu^{2}/\Lambda^{2}))}{\ln(\mu^{2}/\Lambda^{2})}\right].$
(19)

The values of the form factors at zero momentum transfer, $Q^{2}=0$, defines
the corresponding charges. However, in our case, the working region of the
LCSR cannot extrapolate to the $Q^{2}=0$ directly. LCSR results more reliable
at $Q^{2}>1~{}GeV^{2}$. The tensor form factor is parameterized in terms of an
exponential form

$F_{T}(Q^{2})=F_{T}(0)\exp[-Q^{2}/m_{T}^{2}]$ (20)

which makes a reasonable description of data with a two-parameter fit. Our
predictions are presented in Table 2. As seen in Table 2, predictions of old
DAs are more reliable and reasonable than the new DA result. The results of
new DAs are very large and quite suspicious. When one takes the
nonrelativistic limit, the isovector tensor charge becomes identical with the
isovector axial vector charge [1], which is of order similar to the hyperon
isovector axial vector charges [ $g_{A}^{\Sigma}\simeq 1$, $g_{A}^{\Xi}\simeq
0.3$ [42, 43]]. Therefore obtained by using new DAs results unreliable. Some
of the results obtained using the old DAs are consistent but some of them are
not consistent with this prediction.

We give the results for the $H_{T}^{\Sigma}=1.10$ and $H_{T}^{\Xi}=-0.30$
obtained from chiral quark soliton model [12], which have been calculated at a
renormalization scale $\mu=0.36~{}GeV^{2}$. In order to compare our results,
we use the Eq. (16) to the relate this results of form factors to those at
$\mu=1~{}GeV^{2}$, and we obtained these result; $H_{T}^{\Sigma}(0)=1.00$ and
$H_{T}^{\Xi}(0)=-0.27$. As seen from Table 2, our results are different from
the results obtained in the chiral quark soliton model.

| Results of old DAs | Results of new DAs
---|---|---
| Transition
---
| $F_{T}(0)(GeV^{-2})$
---
$m_{T}(GeV)$ | $F_{T}(0)(GeV^{-2})$ | $m_{T}(GeV)$
| $E_{T}(0)=-0.38\pm 0.04$ | $1.31$ | $E_{T}(0)=-115.39\pm 15.44$ | $1.28$
$\Sigma-\Sigma$ | $H_{T}(0)=-0.59\pm 0.11$ | $1.30$ | $H_{T}(0)=-137.72\pm 30.74$ | 0.96
| $\tilde{H}_{T}(0)=-0.10\pm 0.01$ | $1.10$ | $\tilde{H}_{T}(0)=-19.28\pm 2.50$ | 1.48
| $E_{T}(0)=-0.6\pm 0.08$ | $1.93$ | $E_{T}(0)=2160.45\pm 120.44$ | $1.26$
$\Sigma-\Lambda$ | $H_{T}(0)=0.65\pm 0.1$ | $1.74$ |  $H_{T}(0)=135.14\pm 30.14$4 | $1.26$
| $\tilde{H}_{T}(0)=-0.001\pm 0.0001$ | $1.65$ | $\tilde{H}_{T}(0)=-14.76\pm 0.50$ | $1.28$
| $E_{T}(0)=1.09\pm 0.2$ | $1.32$ | $-$ | $-$
$\Xi-\Xi$ | $H_{T}(0)=-3.00\pm 0.6$ | $1.23$ | $-$ | $-$
| $\tilde{H}_{T}(0)=-0.10\pm 0.01$ | $1.22$ | $-$ | $-$
Table 2: The values of exponential fit parameters, $F_{T}(0)$ and $m_{T}$ for
tensor form factor obtained from the old and new DAs analysis of sum rules.

In conclusion, we have evaluated the isovector tensor form factors of octet-
octet hyperons by applying the LCSR. These form factors are related to the
transverse polarization which gives an important piece of information on the
internal structure of baryons (e.g. the transverse spin structure of the
baryons). The $Q^{2}$ dependency of form factors are obtained using the old
and new DA results. The new DA results shows that our predictions of the form
factors are very large. Our predictions on the isovector tensor charges can be
summarized in Table 2. The old DA results seems to be more reliable. Our
results on these form factors are compared with the chiral quark soliton model
predictions. The chiral quark soliton model results only exist for the $H_{T}$
form factor so we cannot compare results of other form factors.

## Acknowledgments

This work has been supported, by the Scientific and Technological Research
Council of Turkey (TUBITAK) under project No. 114F278.

## References

  * [1] R. Jaffe, X.D. Ji, Phys.Rev.Lett. 67, 552 (1991)
  * [2] M. Anselmino, M. Boglione, U. D’Alesio, A. Kotzinian, F. Murgia, et al., Phys.Rev. D75, 054032 (2007)
  * [3] K. Abe, et al., Phys.Rev.Lett. 96, 232002 (2006)
  * [4] A. Airapetian, et al., Phys.Rev.Lett. 94, 012002 (2005)
  * [5] E. Ageev, et al., Nucl.Phys. B765 (2007)
  * [6] I.C. Cloet, W. Bentz, A.W. Thomas, Phys. Lett. B659 (2008)
  * [7] M. Anselmino, M. Boglione, U. D’Alesio, A. Kotzinian, F. Murgia, A. Prokudin, S. Melis, Nucl. Phys. Proc. Suppl. 191 (2009)
  * [8] P. Hagler, et al., Phys.Rev.  D77, 094502 (2008)
  * [9] M. Gockeler, et al., Phys.Rev.Lett. p. 222001 (2007)
  * [10] T. Bhattacharya, V. Cirigliano, S. Cohen, R. Gupta, A. Joseph, H.W. Lin, B. Yoon, Phys. Rev. D92, 094511 (2015)
  * [11] C. Lorce, Phys.Rev. D79, 074027 (2009)
  * [12] T. Ledwig, A. Silva, H.C. Kim, Phys.Rev.  D82, 034022 (2010)
  * [13] I. Schmidt, J. Soffer, Phys.Lett. B407, 331 (1997)
  * [14] B. Pasquini, M. Pincetti, S. Boffi, Phys.Rev. D72, 094029 (2005)
  * [15] J.M. Olness, Phys.Rev. D47, 2136 (1993)
  * [16] L.P. Gamberg, G.R. Goldstein, Phys.Rev.Lett. 87, 242001 (2001)
  * [17] S. Pisano, M. Radici, Eur. Phys. J. A52(6), 155 (2016)
  * [18] H.x. He, X.D. Ji, Phys.Rev. D52, 2960 (1995)
  * [19] H.x. He, X.D. Ji, Phys.Rev. pp. 6897–6902 (1996)
  * [20] T. Aliev, K. Azizi, M. Savci, Phys.Rev. D84, 076005 (2011)
  * [21] G. Erkol, A. Ozpineci, Phys.Lett. B704, 551 (2011)
  * [22] Huey-Wen Lin, Nucl. Phys. Proc. Suppl. 200-207, 2009.
  * [23] M.A. Shifman, A. Vainshtein, V.I. Zakharov, Nucl.Phys. B147, 385 (1979)
  * [24] M.A. Shifman, A. Vainshtein, V.I. Zakharov, Nucl.Phys. B147, 448 (1979)
  * [25] L. Reinders, H. Rubinstein, S. Yazaki, Phys.Rept. 127, 1 (1985)
  * [26] B. Ioffe, A.V. Smilga, Nucl.Phys. B232, 109 (1984)
  * [27] V.M. Braun, I. Filyanov, Z.Phys. C44, 157 (1989)
  * [28] I. Balitsky, V.M. Braun, A. Kolesnichenko, Nucl.Phys. B312, 509 (1989)
  * [29] V. Chernyak, I. Zhitnitsky, Nucl.Phys. B345, 137 (1990)
  * [30] P. Hagler, Phys.Rept.  490, 49 (2010)
  * [31] M. Diehl, T. Feldmann, R. Jakob, P. Kroll, Eur.Phys.J. C8, 409 (1999)
  * [32] V. Braun, A. Lenz, M. Wittmann, Phys.Rev. D73, 094019 (2006)
  * [33] Y.L. Liu, M.Q. Huang, Phys.Rev. D80, 055015 (2009)
  * [34] Y.L. Liu, M.Q. Huang, Nucl.Phys. A821, 80 (2009)
  * [35] Y.L. Liu, C.Y. Cui, M.Q. Huang, Phys.Rev. D89, 035005 (2014)
  * [36] Y.L. Liu, C.Y. Cui, M.Q. Huang, Eur.Phys.J. C74, 3041 (2014)
  * [37] V.M. Braun, A. Lenz, N. Mahnke, E. Stein, Phys. Rev. D65, 074011 (2002)
  * [38] J. Beringer, et al., Phys.Rev. D86, 010001 (2012)
  * [39] T.M. Aliev, A. Ozpineci, M. Savci, Phys. Rev. D66, 016002 (2002)
  * [40] V. Chernyak, I. Zhitnitsky, Nucl.Phys. B246, 52 (1984)
  * [41] V. Barone, A. Drago, P.G. Ratcliffe, Phys.Rept. 359, 1 (2002)
  * [42] G. Erkol, A. Ozpineci, Phys.Rev. D83, 114022 (2011)
  * [43] G. Erkol, M. Oka, T.T. Takahashi, Phys. Lett. B686, 36 (2010)

(a)

(b)

(c)

(d)

(e)

(f)

Figure 1:  The dependence of the form factors; on the Borel parameter squared
$M^{2}$ for the values of the continuum threshold $s_{0}=2~{}GeV^{2}$,
$s_{0}=2.5~{}GeV^{2}$, $s_{0}=3~{}GeV^{2}$, $s_{0}=3.5~{}GeV^{2}$ and
$s_{0}=4~{}GeV^{2}$ and $Q^{2}=2~{}GeV^{2}$, (a) and (b) for $E_{T}^{\Sigma}$
tensor form factor, (c) and (d) for $H_{T}^{\Sigma}$ tensor form factor, (e)
and (f) for $\tilde{H}_{T}^{\Sigma}$ tensor form factor. In here (a), (c) and
(e) are represent results of new DAs and (b), (d) and (f) are represent result
of old DAs.

(a)

(b)

(c)

(d)

(e)

(f)

Figure 2:  The dependence of the form factors; on the Borel parameter squared
$M^{2}$ for the values of the continuum threshold $s_{0}=2~{}GeV^{2}$,
$s_{0}=2.5~{}GeV^{2}$, $s_{0}=3~{}GeV^{2}$, $s_{0}=3.5~{}GeV^{2}$ and
$s_{0}=4~{}GeV^{2}$ and $Q^{2}=2~{}GeV^{2}$, (a) and (b) for
$E_{T}^{\Sigma\Lambda}$ tensor form factor, (c) and (d) for
$H_{T}^{\Sigma\Lambda}$ tensor form factor, (e) and (f) for
$\tilde{H}_{T}^{\Sigma\Lambda}$ tensor form factor. In here (a), (c) and (e)
are represent results of new DAs and (b), (d) and (f) are represent result of
old DAs.

(a)

(b)

(c)

Figure 3:  The dependence of the form factors; on the Borel parameter squared
$M^{2}$ for the values of the continuum threshold $s_{0}=2~{}GeV^{2}$,
$s_{0}=2.5~{}GeV^{2}$, $s_{0}=3~{}GeV^{2}$, $s_{0}=3.5~{}GeV^{2}$ and
$s_{0}=4~{}GeV^{2}$ and $Q^{2}=2~{}GeV^{2}$, (a) for $E_{T}^{\Xi}$ tensor form
factor, (b) for $H_{T}^{\Xi}$ tensor form factor, (c) for
$\tilde{H}_{T}^{\Xi}$ tensor form factor.

(a)

(b)

(c)

(d)

(e)

(f)

Figure 4: The dependence of the form factors on the values of the continuum
threshold $s_{0}=2~{}GeV^{2}$, $s_{0}=2.5~{}GeV^{2}$, $s_{0}=3~{}GeV^{2}$ and
$M^{2}=3~{}GeV^{2}$, (a) and (b) for $E_{T}^{\Sigma}$ tensor form factor, (c)
and (d) for $H_{T}^{\Sigma}$ tensor form factor, (e) and (f) for
$\tilde{H}_{T}^{\Sigma}$ tensor form factor. In here (a), (c) and (e) are
represent results of new DAs and (b), (d) and (f) are represent result of old
DAs.

(a)

(b)

(c)

(d)

(e)

(f)

Figure 5: The dependence of the form factors on the values of the continuum
threshold $s_{0}=2~{}GeV^{2}$, $s_{0}=2.5~{}GeV^{2}$, $s_{0}=3~{}GeV^{2}$ and
$M^{2}=3~{}GeV^{2}$, (a) and (b) for $E_{T}^{\Sigma\Lambda}$ form factor, (c)
and (d) for $H_{T}^{\Sigma\Lambda}$ tensor form factor, (e) and (f) for
$\tilde{H}_{T}^{\Sigma\Lambda}$ tensor form factor. In here (a), (c) and (e)
are represent results of new DAs and (b), (d) and (f) are represent result of
old DAs.

(a)

(b)

(c)

Figure 6: The dependence of the form factors on the values of the continuum
threshold $s_{0}=2~{}GeV^{2}$, $s_{0}=2.5~{}GeV^{2}$, $s_{0}=3~{}GeV^{2}$ and
$M^{2}=3~{}GeV^{2}$, (a) for $E_{T}^{\Xi}$ tensor form factor, (b) for
$H_{T}^{\Xi}$ tensor form factor, (c) for $\tilde{H}_{T}^{\Xi}$ tensor form
factor.


*Ebert Schoofs, Dept. Computer Science, University of Antwerp, Antwerp, Belgium.

# AmPyfier: Test Amplification in Python

Ebert Schoofs  Mehrdad Abdi  Serge Demeyer  Dept. Computer Science, University
of Antwerp, Antwerp, Belgium  AnSyMo, Flanders Make vzw, Antwerp, Belgium
<EMAIL_ADDRESS>Schoofs E  M. Abdi  S. Demeyer

(<day> <Month>, <year>; <day> <Month>, <year>; <day> <Month>, <year>)

###### Abstract

[Abstract] Test Amplification is a method to extend handwritten tests into a
more rigorous test suite covering corner cases in the system under test.
Unfortunately, the current state-of-the-art for test amplification heavily
relies on program analysis techniques which benefit a lot from explicit type
declarations present in statically typed languages like Java and C++. In
dynamically typed languages, such type declarations are not available and as a
consequence test amplification has yet to find its way to programming
languages like Python, Ruby and Javascript. In this paper, we present
AmPyfier, a proof-of-concept tool, which brings test amplification to the
dynamically typed, interpreted language Python. We evaluated this approach on
7 open-source projects, and found that AmPyfier could successfully strengthen
7 out of 10 test classes (70%). As such we demonstrate that test amplification
is feasible for one of the most popular programming languages in use today.

, , and (2021), AmPyfier: Test Amplification in Python, Journal of Software:
Evolution and Process. Special Issue: Automatic Software Testing from the
Trenches, TODO.

###### keywords:

Python, Test Amplification, Unit Test, Mutation Testing

††articletype: Article Type

##  1 Introduction

As proven over and over again, faults are often more expensive to fix than to
prevent. In order to prevent regression and detect bugs, an adequate testing
suite is necessary. To determine the program-based adequacy of a test suite,
multiple criteria exist such as, but not limited to, code coverage
(method/brach/statement) 1 or the mutation score 2. Manually writing a
completely adequate test suite is a labour and time-consuming task. This is
where research concerning test amplification and generation proves to be
useful 3, 4.

Test amplification and generation tools respectively try to automatically
improve a test suite, or generate one based on given criteria. Their goals are
similar, but the difference between amplification and generation is in the
main input it takes. While test generation focuses only on the program under
test, test amplification generates tests based on modification or extension of
the existing handwritten testsuite 5.

In order to automatically improve the mutation coverage of unit tests, Baudry
et al. created DSpot, a test amplification tool for the statically typed
language Java 6. Danglot et al. demonstrated the effectiveness of DSpot, by
running it on 10 mature open source projects. In their experiments, DSpot
successfully improved 26 out of the 40 ($\approx$65%) test classes under study
7. DSpot is able to leverage the fact that Java is a statical typed language,
and typing information can be deduced from a static analysis of the source and
test code.

For dynamically typed languages, test amplification techniques cannot solely
rely on static analysis. To deduce the type of variables and values that are
to be asserted or, in order to support type-sensitive input amplifiers,
dynamic techniques are needed. Abdi et al. have made a proof of concept tool,
Small-Amp with which they showed that test amplification is also possible for
the dynamically typed language Pharo Smalltalk 8, 9. They introduced the
concept of dynamic type profiling, with which they were able to overcome the
lack of type information in the source code. While it is certainly interesting
from an academic point of view that test amplification can be extended from
statically, to dynamically typed languages, no other tools have been developed
or presented to the best of our knowledge.

As dynamically typed languages, such as Python, become increasingly popular,
adequate testing suites are needed. Indeed, the popularity of Python is still
on the rise10, owning to its ease of learning, huge amount of external
libraries, and the further rise of data-mining and AI research. This leads to
more and more projects being written in Python, or parts of it reliant on code
written in Python.

In 2020, Lukasczyk et al. introduced a tool, capable of test generation for
Python, Pynguin 11. Pynguin, however, leverages the techniques used in
statically typed languages through the assumption that the system under test
contains type information with Python’s type annotations. Auger 12 is another
tool that automatically generates tests for Python, but only considers the
given execution of the project under test.

In contrast to the popularity of Python, the research into automatically
improving a test suite for a Python project is still sparse, and especially in
regard to test amplification, non-existent.

With this paper, we extend the concept of test amplification to Python, the
most popular (dynamically typed) language today according to
IEEE111https://spectrum.ieee.org/top-programming-languages/, and present
AmPyfier222https://ansymore.uantwerpen.be/artefacts/ampyfier, a proof of
concept tool. Python is a dynamically typed interpreted language, with a less
strict syntax as for example Smalltalk. Furthermore, despite Python being an
Object-Oriented programming language, it supports multiple programming
paradigms. Python allows a developer to disregard the object-oriented design
and write code following the procedural and functional paradigms.13

We furthermore demonstrate that it is not only feasible, but also effective
for existing open-source projects. In our evaluation on 7 open-source projects
including 10 test classes, AmPyfier successfully amplified 7 test classes
(70%), with one case showing an increase up to 53.06% in the mutation score.
The experimental data is publicly available in our GitHub
repository333https://github.com/SchoofsEbert/AmPyfier_evaluation where the
generated reports, and the amplified test suites can be found.

In the following section, we provide some background, what exactly Test
Amplification is and how it is implemented in DSpot, and Small-Amp.
Furthermore, we give some more background about Python, unit-testing in
Python, and related work in regard to Test Generation for Python. In Section
3, we explain the main algorithms of AmPyfier itself with the help of a
running example, and how the implementation for Python differs from Small-Amp
and DSpot. We have evaluated AmPyfier on 7 open-source projects, the results
are discussed in 4, as well as the lessons we have learned from these
experiments. In the last section, we conclude and discuss further work that
needs to be done.

##  2 Background and related work

###  2.1 Test Amplification

Test amplification can be seen as family of test generation, aimed at
improving a Test Suite against a given criterion. The main difference is, in
test generation, the starting point is the project under test, whereas in test
amplification, the already existing test suite is taken as input. By adopting
methods like test-driven development (TDD), developers write test code during
or before the writing of production code. Consequently, the majority of modern
software projects include a considerable amount of test code. These test
suites often contain meaningful information about the project under test, and
what should be tested. Although these test suites may cover most of the main
scenarios in the code, some of the corner cases may still be missed and remain
untested.

Test amplification is defined as followed by Danglot et al. 5:

> “Test amplification consists of exploiting the knowledge of a large number
> of test cases, in which developers embed meaningful input data and expected
> properties in the form of oracles, in order to enhance these manually
> written tests with respect to an engineering goal.”

They also divide the existing test amplification tools into four categories:

  1. 1.

Amplification by adding new tests as variants of existing ones

  2. 2.

Amplification by synthesizing new tests with respect to changes

  3. 3.

Amplification by modifying test execution

  4. 4.

Amplification by modifying existing test code

###  2.2 Test Amplification Components

A test amplification tool typically consists of four main components. In the
next parts, we provide short descriptions for each component, and lastly, take
a look at related work.

##### Assertion Amplification

This module is responsible for adding missed assertions. A recent assertion
amplification technique proposed by Xie 14 works based on a dynamic analysis
that runs the test to be amplified and captures the object states during the
execution. In this technique the value of getter-methods of an object, or the
return values of function calls are captured then extra assertion statements
are added.

##### Input Amplification

Test input is all statements in a test code except the assertion statements.
With input amplification, new versions of test input are generated based on
the existing test input. The amplified test input may take a different
execution path or bring the objects under test into new states. In other
words, the input amplification component empowers a test amplification tool to
explore the search space of all possible tests.

DSpot uses an input amplification technique inspired by ETOC 15. In this
technique, a test input is modified statically by a set of input amplification
operators, and new versions of the test input are generated. Input
amplification operators range from changing the literal values by simple
arithmetic operations on integers and modifications of strings to addition,
duplication, or removal of method and function calls. Multiple such amplifiers
are applied after each other to combine the different ways in which a test is
modified.

##### Selection

The goal of test amplification is to improve the tests in regard to a
quantifiable engineering goal, expressed as a metric. Possible metrics are:
coverage or mutation score improvement, fault detection capability
improvement, oracle improvement, and debugging effectiveness improvement 5.
Test Amplification tools generate lots of new tests derived from the existing
test suite. The selected metric is calculated for each newly generated test.
If it is able to improve the metric value, the generated test method is
selected as an amplified test method otherwise it is discarded.

##### Type Profiling

Performing static analysis in dynamically typed languages like Python yields
less information than in statically typed languages because the source code in
dynamic languages does not include type information. Adding a new method call
is an example of a type-sensitive input amplifier. To generate new arguments
for new method and function calls, typically we need to know which input type
to pass to the call. For statical typed languages, such as Java, we can derive
the types of the input through a static analysis of the project under test,
but for languages such as Python, we need to derive the types dynamically.
Since the existing test suite is one of the main inputs in test amplification
tools, performing dynamic type profiling by running the existing test suite is
possible. The concept, introduced by Small-Amp, is to run the existing test
suite and capture (1) the type of arguments in the methods under test (2) the
type of variables in the original test methods.

####  2.2.1 Related work: DSpot and Small-Amp

AmPyfier is the adoption of the algorithms introduced in DSpot and Small-Amp
into the Python ecosystem. Whereas DSpot is developed for the statically typed
language Java, Small-Amp performs test amplification for the dynamically typed
language Pharo Smalltalk. Both amplify the test suite through the addition of
new tests as variants of the existing ones. New tests are generated based on
the existing tests and added to the test suite based on a given acceptance
criterion.

The main amplification algorithms used in DSpot and Small-Amp, and now
AmPyfier are quite similar. They repeat the input amplification, assertion
amplification, and selection steps iteratively for all existing test methods.
Mutation Coverage is proposed as a selection criterion in DSpot, and is taken
over by Small-Amp. AmPyfier uses a multi-level metric for selection whereas it
detects the improvements based on code coverage and mutation testing. In other
words, it computes the mutants only in the covered parts of code, and a
generated test method is selected if it is able to increase either test
coverage or killed mutants.

To know the values to be asserted in the assertion amplification step, DSpot
and Small-Amp both use the same technique. First, the statements of interest
are encapsulated in observation statements, and the test is executed. The
results are collected and, based on the observations, the assertion statements
are constructed. AmPyfier tackles this problem in a similar manner, albeit
with a different implementation technique. It leverages the fact that Python
is interpreted and uses python sys.settrace() function. An in depth discussion
can be found in subsection 3.4.

For gathering the type information, Small-Amp introduces a dynamic type
profiling step before the main loop of the algorithm. To extract this
information Small-Amp adds Metalinks on all variables in a test method.
Metalink16 is a fine-grained reflection mechanism, that allows to install AST
node level proxies. Subsequently, Small-Amp runs the test. The meta-links are
fired when the variables are used to capture the type-information in the run-
time. This type information is then used, during Input Amplification, to
select another variable in the test to use as input for the newly added
method.9 AmPyfier however, is able to leverage the Python Interpreter instead
of Metalinks to gather such information. See 3.5 for a more in depth
explanation.

###  2.3 Python

Python is a dynamically typed interpreted language, which supports multiple
programming paradigms. Python doesn’t force developers to write their code in
an object-oriented manner and encapsulate all functionality in classes,
allowing developers to write code following multiple programming paradigms. In
the background, however, everything in Python is an object, even the current
stack frame. This fact is leveraged by the Python Tracer, which allows to
dynamically obtain all necessary information about what is happening in the
project under test during execution.

While everything is an object according to the inner workings of Python,
Python has no notion of encapsulation. Private or protected attributes can not
be enforced. Every attribute is public, and can be accessed from everywhere.
It is up to the developer to follow the coding conventions where an attribute
should be considered protected if it is prefixed with one underscore (e.g.
_protected_attribute), and private if it is prefixed with two underscores
(e.g. __private_attribute).

Not only attribute access is very relaxed, but Python also has a very relaxed
import system. Different import statements can be used for the same import
behaviour. It is possible to only import a single variable, function, or class
from a module, or to import a whole package consisting of multiple files. Such
a package needs to have an __init__.py file, which can contain code, or import
statements on its own. Furthermore, it is not necessary to define all the
imports at the beginning of the file. It is possible to import modules from
inside functions or even loops for example. The code in an imported module or
package is always executed upon import. This flexible import system is
challenging for test amplification because we must establish the class under
test for a given test case.

It is possible in Python to pass a custom traceback function to the Python
interpreter with the sys.settrace() function. Those custom trace functions
make it possible to investigate the execution of a Python project, and collect
runtime information before certain events occur, such as a new line, a
function call, or the occurrence of an exception. The current stack frame, as
well as the event type and a possible argument, are passed to the custom trace
function and can be inspected. From this stackframe, for example, it is
possible to access the variables currently in scope. The inspect module
elevates this further and provides several useful functions to help get
information about live objects such as modules, classes, methods, functions,
tracebacks, frame objects, and code objects 17. For example, it allows to get
all members of an object with the getMembers() function, or the name of a
module some function was defined in using getModule(). The inspect module can
even return the specific source code of an object or method definition with
getsource().

Python is an idiomatic language 18, for doing a specific task, there is only
one typical, well-known and optimal way. Other ways are not preferred even if
they are grammatically correct. Since following the idioms makes the code more
readable and easier to maintain, it is important for tools like AmPyfier,
which synthesize code portions, to support such guidelines.

####  2.3.1 Unit testing in Python

Unit testing in Python has no straightforward conventions. Since Python
projects don’t have to follow object-oriented design, a unit can be seen as
both a module or a class. Additionally, Python has multiple unit test
frameworks, which can function completely differently. Two of the most popular
are the default unittest framework included in the Python Standard Library,
and Pytest444https://pytest.org.

Unittest is inspired by the unit testing framework for Java, JUnit. All test
methods should be contained in a class derived from the unittest.TestCase. A
single test file can consist of multiple such classes. A test suite can be
considered as a single test file, or a collection of test files. In this
paper, we refer to a Test Suite as one test file, possibly containing multiple
test classes.

####  2.3.2 Test generation in Python and related work

In regard to test amplification, no tools have been developed for Python to
the best of our knowledge. On the other hand for test generation, there has
already been done some work.

In 2020 Lukasczyk et al. introduced Pynguin 11. A tool that can automatically
generate unit tests for Python. However, Pynguin implements the test
generation techniques of whole-suit generation4 and feedback-directed random
generation19, established for statically typed languages and uses them on
Python. Therefore, Pynguin is most effective under the assumption that the
system under test contains type information with Python’s type annotations. It
thus does not completely address Python’s dynamic nature.

Another tool that automatically generates unit tests for Python is Auger 12,
introduced in 2016. Auger leverages the Python Tracer and tracks function
calls related to the module under test. If a function is called that is
defined in the module under test, Auger keeps track of both the values of the
arguments as well as the return values. Based on those values, assertions can
be generated. Auger thus does not need to rely on type annotations, but only
generates tests for the given execution of the project under test. If a
function is not called, it won’t be tested. Furthermore, it doesn’t handle
exceptions very well.

While both Pynguin and Auger could be used as a good starting point to develop
a test suite, they both have their limitations. Pynguin relies on type
annotations, whilst Auger does not test non-executed code.

##  3 AmPyfier

In this section, we present AmPyfier. In section 3.1 we present the running
example, used to explain the working of AmPyfier in the subsequent
subsections. A broad overview of the main algorithm is given in section 3.2.
Section 3.3 explains how AmPyfier discovers the module under test despite
Python’s flexible import system. In sections 3.4 and 3.6, the main differences
in assertion and input amplification for Python are set out. Lastly, the
selection of tests is described in section 3.7

###  3.1 Running Example

To explain the workings of AmPyfier, we use a running example, namely a simple
fund implementation: SmallFund. See listing 1 for the source code of
SmallFund. The SmallFund class in our running example has five public methods;
get_balance, deposit, is_empty, get_transactions and get_self. Furthermore, it
has two protected attributes (_balance and _transactions) and one public
attribute (owner).

⬇

1class SmallFund:

2 def __init__(self, owner):

3 self._balance = 0

4 self._transactions = []

5 self.owner = owner

6

7 def get_balance(self):

8 return self._balance

9

10 def deposit(self, amount):

11 if amount >= 0:

12 self._balance += amount

13 self._transactions.append( amount)

14 else:

15 raise Exception("Can␣not␣deposit␣negative␣amounts")

16

17 def is_empty(self):

18 return self._balance == 0

19

20 def get_transactions(self):

21 return self._transactions

22

23 def get_self(self):

24 return self

Listing 1: The SmallFund class

The manually created test suite for SmallFund is presented in listing 2. This
test suite covers the main scenario of depositing positive amounts. However,
it does not cover corner cases like depositing an $amount$ less than zero.

⬇

1import unittest

2from SmallFund import SmallFund

3

4class SmallFundTest(unittest.TestCase):

5 def setUp(self):

6 self.b = SmallFund("Iwena␣Kroka")

7

8 def testDeposit(self):

9 self.b.deposit(10)

10 self.assertEqual( self.b.get_balance(), 10)

11 self.assertIsInstance( self.b.get_self(), SmallFund)

12 self.b.deposit(100)

13 self.b.deposit(100)

14 self.assertEqual( self.b.get_balance(), 210)

Listing 2: Original test suite

###  3.2 Logic

The logic of AmPyfier is shown in Algorithm 1. The main algorithm is inspired
by the work of DSpot, and also makes use of type profiling similar to Small-
Amp. The default input is a single Python test file, the Test Suite (TS), the
list of amplifiers/mutators (A), and the number of subsequent amplifier runs
($n$).

1

input : Test Suite TS

input : List of amplifiers A

input : Number of Input Amplifier runs $n$

output : Amplified Test Suite ATS

2

3ATS $\leftarrow\emptyset$;

4 for  _TC in TS_ do

5 $mut$ $\leftarrow$ FindModuleUnderTest(_TC_);

6 ATC $\leftarrow$ TC;

7 $score$ $\leftarrow\textnormal{{Selection}}($ATC, $mut)$;

8 for  _$test$ in TC_ do

9 $a\\_test$ $\leftarrow$ AssertionAmplify(_$test$ , $mut$_);

10 $a\\_score$ $\leftarrow\textnormal{{Selection}}($ATC $\cup$
$\\{a\\_test\\},mut)$;

11 if  _$a\\_score$ > $score$_ then

12 ATC $\leftarrow$ ATC $\cup$ $\\{a\\_test\\}$;

13 $score\leftarrow a\\_score$;

14

15 $tp$ $\leftarrow$ TypeProfile(_TC, test_);

16 IT $\leftarrow$ InputAmplify(_$a\\_test$ , A, $n,tp$_);

17 $score$, IIT $\leftarrow\textnormal{{Selection}}($ATC $\cup$ IT, $mut)$;

18 ATC $\leftarrow$ ATC $\cup$ IIT;

19

20 ATS $\leftarrow$ ATS $\cup$ ATC;

21

Algorithm 1 AmPyfier logic

AmPyfier iterates over each test class (TC) in the Test Suite and finds the
module under test ($mut$) for this Test Case555Since all test classes are
inherited from the class unittest.TestCase, we use the name test class and
test case interchangeably.. This module can be a single Python file, or a
package consisting of multiple files. Afterwards, AmPyfier scores the current
Test Case against the module under test using the multi-level coverage
calculator. The variable score contains a tuple of absolute coverages. We
explain it in more details in section 3.7.

The inner loop (lines 1 to 1) loops over each test in the Test Case, and
Assertion Amplifies it. If the assertion amplified test ($a\\_test$) improves
the current score, it is added to the Amplified Test Case (ATC).

After a test case is assertion amplified, the original test is passed to the
Type Profiler in order to dynamically obtain information about the various
types used in the method or function calls in this test. The amplified test,
the amplifiers to use, and the number of input amplification iterations and
also the profiled type information are passed to the input amplifier. The
input amplifier, which encompasses an assertion amplification run at the end,
returns a set of input amplified test methods (IT).

Finally, the input amplified tests are scored, and the current score is
updated (line 1). The input amplified tests that improved the current score
are appended to the amplified test case. Once each test method is amplified,
the amplified test case is added to the amplified test suite. At the end, each
amplified test case is added to the Amplified Test Suite, which is returned
after each Test Class is amplified.

AmPyfier currently only supports the unittest framework. The reason why
unittest is preferred to be supported first is: (1) it is the standard testing
library proposed by the language, (2) it complies with xUnit testing practices
similar to JUnit in Java and sUnit in Smalltalk. However, the tool is
developed in an extensive way that support for other frameworks, such as
Pytest, can be added.

###  3.3 Discovering the module under test

The first task AmPyfier needs to solve is to determine the module under test
for each individual test class. Because of Python’s very flexible import
system, as discussed in 2.3, this is no obvious task. AmPyfier tackles this
problem using the following technique:

  * •

First, an inspection of the imports of the test class is performed and
imported modules belonging to the project under test are stored.

  * •

Subsequently, all function calls and constructors are observed. The module
that is used the most in the test case is considered the module under test.

In case AmPyfier fails to detect the right module under test, AmPyfier reports
on this, and the whole class is skipped. The module under test can also be
provided as a configuration argument. In the case the module under test is
passed as an argument, it is used for the whole test suite.

###  3.4 Assertion Amplification

Algorithm 2 shows how Assertion Amplification is implemented in AmPyfier. It
consists of four steps: (1) firstly, the assertions are stripped from the
test. (2) secondly, the test without assertions is executed and observations
are constructed. (3) then, execution and collecting the observations are
repeated F times. These observations then are compared and all non-
deterministic observations are discarded. (4) Finally, (new) assertions are
constructed based on those observations.

1

2

input : Test Method test

input : Unit under Test unit

output : Assertion Amplified Test Method amplified

3

4amplified $\leftarrow$ RemoveAssertions(_test_);

5 observations $\leftarrow$ Observe(_amplified, unit_);

6 for  _$F$ times _ do

7 observations2 $\leftarrow$ Observe(_amplified, unit_);

8 if  _observations $\neq$ observations2_ then

9 observations $\leftarrow$ RemoveNonDeterministic(_observations,
observations2_);

10

11

12amplified $\leftarrow$ AddAssertions(_amplified, observations_);

Algorithm 2 Assertion Amplification

The first step is to remove the original assertions. The test source is
scanned statically and all method calls that are known as an asserting
statement are replaced with their asserted expression.

The second step is observing the test method. The test method is dynamically
executed and the values of the variables and the state of the objects are
captured. For observing the values, DSpot and Small-Amp manipulate the source
code to inject observation statements. However, Python is an interpreted
language and lots of information is accessible during runtime. AmPyfier uses
Python sys.settrace() function along with a set of custom trace functions to
hook in different points during the execution and observe the objects’ states
and collect the return values of function calls.

The observations of the state of objects are also made possible thanks to the
interpreted nature of Python. Python has a built-in module inspect enabling
the possibility to derive all information about live objects during runtime,
such as their state, the module and file it was defined in, the name, ….
AmPyfier uses a custom method based on inspect.getmembers() to get all the
public attributes and methods of an object, and stores them in the
observation. This custom method is exactly the same as inspect.getmembers(),
except it adds the possibility to also capture members or variables that cause
exceptions instead of simply raising them. This proves its usefulness after
input amplification, where AmPyfier may have pushed an object in an erroneous
state.

When AmPyfier extracts an assertRaises statement, the extracted statement will
raise an exception. Exceptions also occur when the test input is mutated by
the Input Amplification module. So, it is crucial for AmPyfier to be able to
handle the exceptions correctly during observation of the test method. When
the observation process is interrupted by an exception, AmPyfier finds the
line causing the exception. Then, it wraps this line in a Try-Catch block and
restarts the observation process. This allows AmPyfier to assert raised
exceptions on a per-line basis, and still assert the other statements in a
test.

To prevent generating flaky tests, AmPyfier excludes all non-deterministic
values from the observations. AmPyfier uses a configurable constant F and
repeats the observing process F times. After each iteration, the observation
sets are compared, and the non-deterministic observations are removed.

After the test has been observed and the values to be asserted collected, the
final step is to construct the assertion statements. AmPyfier loops on a line
per line basis over the method-body, and constructs the assertions based on
the observations originating from that line.

Listing 3 shows our running example test method testDeposit after assertion
amplification.

⬇

1def testDeposit_amp(self):

2 self.b.deposit(10)

3 self.assertEqual( self.b.get_transactions(), [10])

4 self.assertFalse( self.b.is_empty())

5 self.assertEqual( self.b.owner, ’Iwena␣Kroka’)

6 self.assertEqual( self.b.get_balance(), 10)

7 self.assertIsInstance( self.b.get_self(), SmallFund)

8 self.b.deposit(100)

9 self.assertEqual( self.b.get_balance(), 110)

10 self.assertEqual( self.b.get_transactions(), [10, 100])

11 self.assertFalse( self.b.is_empty())

12 self.assertEqual( self.b.owner, ’Iwena␣Kroka’)

13 self.b.deposit(100)

14 self.assertEqual( self.b.get_transactions(), [10, 100, 100])

15 self.assertFalse( self.b.is_empty())

16 self.assertEqual( self.b.owner, ’Iwena␣Kroka’)

17 self.assertEqual( self.b.get_balance(), 210)

Listing 3: Assertion Amplified test method

###  3.5 Type Profiler

Before the assertion amplified test is passed to input amplification, it is
passed to the type profiler. Since input amplification is mainly performed
statically, some type-sensitive input amplifiers, such as the addition of a
new method call, need type information in advance.

Python is a dynamically typed language and does not force developers to add
type information to the source code. Python supports type annotations since
Python 3, but there is no guarantee that developers annotate types during
development. In addition, annotations defined for functions and variables are
not enforced by the python runtime and they are only used by third-party tools
like IDEs and linters, so there is no guarantee that they are defined
correctly 20. As a consequence, AmPyfier does not rely on the annotated types
in the source code and uses a dynamic type profiling step to collect type
information.

Dynamic type profiling is introduced by Small-Amp for test amplification in
dynamically typed languages 9. In simple words, the type profiler exploits the
fact that it is possible to extract type information dynamically by executing
the existing test suite. As is mentioned in section 2.1, the existing test
suite is the main input in the algorithm and lots of useful information about
the project under test are embedded inside.

The test suite as well as the test method to be amplified are executed in
order to detect the type of arguments in the methods and functions under test.
This type profiler works similar to the Observing step in assertion
amplification, and leverages the ability to pass custom tracing functions to
the Python interpreter through the sys.settrace() function. Allowing AmPyfier
to monitor calls executed in the test method, and discover the possible types
used as input for different method and function calls. With this information,
new method, or function calls can be generated as well as their random inputs.

###  3.6 Input Amplification

The algorithm for input amplification in AmPyfier is presented in listing 3.
Input Amplification starts similar to Assertion Amplification, namely,
stripping the tests of its assertions again. Then we loop over all the
amplifiers $n$ times in order to combine different amplifiers. This loop
generates loads of new tests, so each time we have looped over the amplifiers,
only $T$ randomly selected tests are kept. Those $T$ tests are added to the
results, and also passed on to the next iteration. Once the $n$ iterations are
completed, all the selected tests are assertion amplified. Finally, the
assertion amplified tests are sorted on their modification count, and
returned.

1

input : Test method test

input : Number of iterations n

input : List of amplifiers AMPS

input : Typing information tp

output : Input Amplified Tests AT

2

3$temp$
$\leftarrow\\{~{}\textnormal{{RemoveAssertions(}}\textnormal{\emph{test}}\textnormal{{)}}\\}$
;

4 $results\leftarrow\emptyset$;

5 for  _$n$ times_ do

6 $amplified$ $\leftarrow\emptyset$ ;

7 for  _$amp$ in $AMPS$_ do

8 $amplified$ $\leftarrow$ $amplified\cup amp.apply(temp,tp)$;

9

10 if  _Size(_$amplified$_) > $T$_ then

11 $amplified$ $\leftarrow$ SelectRandom(_$amplified$ , $T$_)

12 $results\leftarrow results\cup amplified$;

13 $temp\leftarrow amplified$;

14

15AT $\leftarrow$ AssertionAmplify(_$results$_);

16 AT $\leftarrow$ Sort(_AT_);

Algorithm 3 Input Amplification

In order to input amplify the test, we need to strip the test from any
assertions. Statements that were asserted in the original test method are
extracted, whereas amplified assertions are completely removed. If the
assertions were kept in the test, the test would fail on the amplified inputs.
Furthermore, we want to construct new assertions based on those amplified
inputs.

Once stripped from assertions, AmPyfier loops over the list of selected
amplifiers $n$ times. Each time the loop over the amplifiers is completed, new
tests are generated, increasing the number of tests exponentially for each
loop. To counter this, after each loop, only a configurable amount of tests
($T$) is randomly selected and passed on to the next loop. The default value
of $T$ is 200.

The amplifiers used in input amplification are based on the ones used in DSpot
and Small-Amp:

  * •

Literal Mutation:

    * –

Numerical Values: $0,+1,-1,*2,/2$

    * –

Strings: add random char on empty string, double the string, random substring
of half the size, replace with empty string

    * –

Booleans: negation

    * –

Unification of literals

  * •

Mutation of Method Calls:

    * –

Removal

    * –

Duplication

    * –

Addition of a new method call

In listing 3.6, the assertion amplifed method in listing 3 is shown during
stages of Input Amplification. The listing on the left, is the method after
stripping the assertions, and the listing on the right is the method after
three transformations: 1) One method call has been removed at line 2, 2) at
line 3, a new call to a random method is added with a random input value of
the correct type, 3) and another call is removed at line 7. Note that, the
unit under test used in this example has only three methods, of which two are
getters. So, the only interesting method which can thus be added, deposit() is
generated.

⬇

1def testDeposit_stripped(self):

2 self.b.deposit(10)

3

4 self.b.get_balance()

5 self.b.get_self()

6 self.b.deposit(100)

7 self.b.deposit(100)

8 self.b.get_balance()

⬇

1def testDeposit_i_amplified(self):

2 # removed statement

3 self.b.deposit(-45485) # new statement

4 self.b.get_balance()

5 self.b.get_self()

6 self.b.deposit(100)

7 # removed statement

8 self.b.get_balance()

After the Input Amplifier loop is finished, all newly generated tests are
Assertion Amplified, and sorted depending on the number of modifications:

$N_{modifications}=N_{all\\_assertions}+N_{transformations}-N_{original\\_assertions}$

Adding a new assertion statement counts as one modification, the same for any
modification made through Input Amplification. Regenerating the original
assertions is not counted as a modification. The Input and Assertion Amplified
test (listing 4), in our example, has a modification count of 7: it has 3
transformations, 4 new assertions are added and 3 assertions are regenerated.

Sorting helps AmPyfier to prefer methods that differ the least from the
original test method, or those which have the least new assertions. So, if two
different amplified tests kill the same mutant, the test with the lowest
modification count is selected.

⬇

1def testDeposit_amplified(self):

2 with self.assertRaises(Exception):

3 self.b.deposit(-45485)

4 self.assertEqual( self.b.get_balance(), 0)

5 self.assertIsInstance( self.b.get_self(), SmallFund)

6 self.b.deposit( 100)

7 self.assertEqual( self.b.get_transactions(), [100])

8 self.assertFalse( self.b.is_empty())

9 self.assertEqual( self.b.owner, ’Iwena␣Kroka’)

10 self.assertEqual( self.b.get_balance(), 100)

Listing 4: Assertions & Input Amplified test method

###  3.7 Multi-Metric Selection

Input Amplification yields large amounts of new test methods, and most of them
do not increase the coverage, thus a method to decide on which tests to add to
the Amplified Test Class is needed. This method scores the current amplified
test case with the addition of a newly generated test based on a given
adequacy criterion. AmPyfier mainly uses the same criterion as suggested by
DSpot: the number of mutants a test suite is capable to kill.

One of the main downsides of mutation testing is that, naively, a test has to
be executed the same number of times as there are mutants. For test
amplification, this means that a test has to be executed the number of mutants
times the number of amplified tests. It comes as no surprise that reducing the
number of mutants against which have to be tested can drastically decrease the
runtime.

Adopting the experience of mutation testing in Google 21, the tool generates
mutants only in the covered lines of code. However, this practice has as a
result that amplified tests that reach previously non-covered code won’t be
selected, because they do not kill any mutant. Therefore, AmPyfier introduces
multi-metrics selection: the usage of code coverage along with mutation
testing. A test is selected if it increases the code coverage or it kills new
mutants. Furthermore, if an amplified test reaches previously uncovered code,
new mutants are generated for those lines.

Python has many capable mutation testing frameworks, but the one used by
AmPyfier is mutaTest666https://github.com/EvanKepner/mutatest. This framework
is chosen thanks to the extensive API that allows for the introduction of
caching. AmPyfier thus does not need to retest for every mutant that is
already killed and can throw away mutants that result in time-outs,
drastically decreasing the runtime of AmPyfier. To derive the coverage score
of a test, AmPyfier makes use of the Coverage.py
framework777https://github.com/nedbat/coveragepy.

The return value score is a tuple of the absolute number of covered elements.
The first element of this tuple shows the number of all covered lines, and the
second element shows the number of killed mutants. This variable is used in
the main algorithm (Algorithm 1) to detect any improvements in the coverage.

##  4 Evaluation

To evaluate AmPyfier, we have run it using the default configuration on
multiple test files from multiple small open-source projects found on GitHub.
In total, we have evaluated AmPyfier on 10 test classes as can be seen in
Table 1. Those projects are selected based on recent activity and the fact
that they have more than 50 stars on GitHub. Furthermore, their test suites
had to have been developed using Python’s standard unittest framework. The
original coverage and mutation scores of the test classes range from a very
low score to a very high score. The goal is to test to which extent AmPyfier
is still able to increase the mutation score, even for test suites with an
already high mutation score. All classes without any alive mutants are
rejected because they have no room to improve. The results of our evaluation
are publicly available in our GitHub
repository888https://github.com/SchoofsEbert/AmPyfier_evaluation.

Project | Repository | Selected test class
---|---|---
Python Twelve Tone | https://github.com/accraze/python-twelve-tone | tests.test_composer.TestMatrix
Pippin Nano Wallet | https://github.com/appditto/pippin_nano_wallet | tests.validator_tests.TestValidators
|  | tests.crypt_tests.TestAESCrypt
Whois | https://github.com/richardpenman/whois | tests.test_main.TestExtractDomain
PyPDF2 | https://github.com/mstamy2/PyPDF2 | tests.tests.PdfReaderTestCases
|  | tests.tests.AddJsTestCase
Addict | https://github.com/mewwts/addict | test_addict.DictTests
|  | test_addict.ChildDictTests
MPyQ | https://github.com/eagleflo/mpyq | test.test_mpqarchive.TestMPQArchive
PJ | https://github.com/eatonphil/pj | tests.test_pj.TestStringMethods
Table 1: Projects amplified with AmPyfier

The default configuration of AmPyfier is a) the usage of the cache to minimize
runtime, b) automatic discovery of the module under test c) 2 observation runs
to counter flaky tests d) 200 tests can be collected during each loop inside
the Input Amplification part, e) there are 3 of these loops, and f) all
amplifiers discussed in section 3.6 are used.

The results of this experiment are presented in Table 2. The second and third
columns (%MSO, and %MSA) in this table represent the mutation score before,
and after test amplification. The forth column (%MSI) shows the increase in
the mutation score which is the difference of third and second columns. The
column %RMSI represents the relative increase in the killed mutants.

$\%RMSI=100*\frac{\\#Mutants.killed_{Amplified}-\\#Mutants.killed_{Original}}{\\#Mutants.killed_{Original}}$

The columns #MO and #MA represent the number of test methods in the original
test class, and the number of amplified test methods produced by AmPyfier.

Test classes | %MSO | %MSA | %MSI | %RMSI | #MO | #MA
---|---|---|---|---|---|---
TestMatrix | 89.29 | 89.29 | 0 | 0 | 5 | 0
TestValidators | 86.57 | 89.55 | 2.99 | 3.45 | 2 | 2
TestAESCrypt | 91.43 | 98.57 | 7.14 | 7.81 | 1 | 4
TestExtractDomain | 2.69 | 55.84 | 53.15 | 1975.86 | 7 | 4
PdfReaderTestCases | 49.73 | 54.08 | 4.35 | 8.75 | 2 | 2
AddJsTestCase | 48.08 | 48.08 | 0 | 0 | 2 | 0
DictTests | 84.06 | 86.96 | 2.90 | 3.45 | 63 | 2
ChildDictTests | 84.06 | 86.96 | 2.90 | 3.45 | 63 | 2
TestMPQArchive | 59.47 | 59.47 | 0 | 0 | 5 | 0
TestStringMethods | 95.59 | 96.32 | 0.74 | 0.77 | 10 | 1
Table 2: The result of evaluation AmPyfier on 10 test classes

AmPyfier is able to increase the mutation score for 7 out of the 10 classes
(70%). The increase in mutation score ranges from 0.74% in a well tested
project to 53.06% in a poorly tested project (poorly tested in regard to the
mutation score). Furthermore, based on the column #MA we see that these
improvements are made mostly through the addition of just a few test methods.

###  4.1 Lessons learnt

Next, we investigated the classes where we did not see any improvement. In
this section we share what we learnt from this investigating:

##### Amplification of pickles is challenging.

Python has the ability to (de-)serialize the structure and states of objects,
whereby the object is converted into a bitstream or vice-versa. This makes it
possible to read and write objects to files or send them across a network. The
process is called Pickling and makes use of the pickle module. It is very
important when trying to pickle and unpickle an object that it is imported the
same way.

Since AmPyfier works based on mutation testing and the unit under test may be
mutated, pickling can cause exceptions during the execution of the test
method, either during observation or selection. That is the main reason we
mostly do not see any improvement in test methods that specifically test the
pickling of an object.

We encountered this problem in two test classes, namely DictTests and
ChildDictTests of the project Addict. However pickling is only tested in one
of the 63 methods, so increase in mutation score was still possible for both
classes.

##### Amplification of file-based tests is not effective.

A similar situation happens when the test works based on file inputs. In such
a test method, a file is opened and the object under test is initialized based
on its content. In these cases, current input amplification operators are not
efficient, because they only consider the test source code and generate new
inputs by mutating it. They can not manipulate the content of the files to
force the test to new states.

For example, in the test class PdfReaderTestCases, one of the test methods
opens a PDF file and initializes a PdfFileReader object from the content of
the file. Then it uses the initialized object to assert some values. Literal
input amplification operators in this test have low effectiveness because they
mutate the string of the file path. Such mutations only generate an incorrect
file path, which causes the raising of an exception, and does not permit
AmPyfier to explore the search space of possible test inputs.

In total, three test classes had this problem, namely the above mentioned
PdfReaderTestCases and AddJsTestCase of the PyPDF2 project and TestMPQArchive
of MPyQ. In only one of those three classes we were able to increase the
mutation score.

##### Smarter assertion generation for complex objects is needed.

In assertion amplification, AmPyfier needs to convert the observed
object/value into an AST representing that object. This process is fairly
simple for asserting literals, or lists/dictionaries consisting of literals.
However, for complex objects this more challenging. DSpot and Small-Amp,
record the values from getters and public attributes of each object. If the
value is also another object, it repeats the process for it up to a defined
depth. However, this technique easily clutters the test with a large amount of
extra assertions, rendering the test unreadable.

For example, suppose generating assertions for a Matrix implementation. The
observer based on public getters observe matrix[1,1] in depth 1,
matrix.row(1)[1], matrix.column(1)[1] and matrix.transpose()[1,1] in depth 2,
and …, while all these observations refer to a single element. As a result,
plenty of unnecessary assertions are generated. Hence, it is important to make
assertion amplification module more smarter.

Additionally, some developers define customized assertions, or helper methods
that contain a set of assertions for specific types. The test generator should
be consistent with such a coding style, which it currently doesn’t do. A
possible solution is using the profiling module to profile how an object is
asserted in the existing test suite. Using this mechanism, the assertion
amplification module would learn from developers how to assert objects and
would produce similar code.

##### Helper methods needs to be considered.

Developers frequently use helper methods in their tests. A helper method is
another method defined in the test suite, but it is not a test method. It can
be defined for different reasons like grouping a set of assertions to reuse
them in different test methods, or setting up an object and bringing it to a
particular state.

If a helper method includes assertion statements, it is necessary to consider
stripping them before input amplification. In our experiments, for example the
class AddJsTestCase uses such helper method. As a result, the amplification of
this class has not been successful, because the majority of input amplified
tests were failing. Helper methods that are defined for altering inputs also
need to be considered in input amplification for increasing space exploration.

Helper methods were only used in the above mentioned AddJsTestCase.

The presence of a helper method is one of the main differences between a test
generation and a test amplification tool. In test generation, the tool starts
to generate the tests from scratch and the structure of a test is defined by
the tool. However, in test amplification, the tool needs to adopt the style of
the existing test suite and consider its elements.

##### Idiomatic Python Code

Test amplification is a program synthesis task which generates new test
methods based on existing ones. The generated test methods needs to be merged
into the code base to make the effect of improved tests permanent. Therefore,
it is important that the generated code is readable and adheres to the
idiomatic coding conventions 18.

In the current implementation of AmPyfier, the test method are changed via
input amplification operators which make subtle changes to the original test
code. So, if the original test code follows Python coding idioms, the
transformed code is likely to follow the same idioms. Additionally, when
generating new method calls and asserting values, AmPyfier respects the Python
conventions in accessing private and protected members. If we decide to extend
Ampyfier with more complex input amplifiers, then the idiomatic nature of the
code transformation should be taken into account.

Nevertheless, AmPyfier currently does not choose meaningful names for the
generated test methods, as for instance done by Nijkamp et. al. 22. The tool
also adds plenty of assertions, some of which are irrelevant, which has a
negative effect on the readability of the generated code. So, the produced
test code is not immediately ready to be merged to the code base and it need a
revision by a developer.

##### Continuous test amplification may help

Lastly, as already briefly touched upon, the main downside to AmPyfier, and
Test Amplification in general, is its complexity. It is a time-, and resource-
consuming task. At worst, each test has to be executed the amount of mutants
times the amount of amplified test generated times, to score them all.
Furthermore, multiple runs of the test are needed during assertion
amplification to evade flaky tests, or to observe tests after an exception
occurred. This makes it difficult to introduce test amplification into
realistic devlopment environments.

Therefore, we suggest employing AmPyfier in the CI pipeline to be triggered
periodically or in each code push to amplify the recent changes. In this case,
the mutants would be generated only for the changed portions of code, and
consequently the amplified tests should cover the changes. This can
significantly reduce the load of execution. The amplified tests and other
reports can be exported as artifacts, or they can be automatically sent as
pull requests to be reviewed by the developers.

##  5 Conclusion

In this paper, we introduced AmPyfier, a test amplification tool for Python, a
dynamically typed and interpreted language. To built the tool we heavily
relied on the design of DSpot, a test amplification tool for the statically
typed language Java. Yet, to overcome the shortcomings of a dynamically typed
language, we incorporated type profiling as used by Small-Amp for the
dynamically typed language Smalltalk. For Python specifically, we leveraged
the fact that it is an interpreted language, where lots of information is
available at runtime via reflective facilities such as the sys.settrace()
function and the inspect module. AmPyfier introduces a way to decrease the
runtime of test amplification for large projects through the usage of multi-
level metrics, where we amplify against code coverage before amplification on
mutation score.

We evaluated AmPyfier on 7 open-source projects, and found that the tool could
successfully strengthen 7 out of 10 test classes (70%). This is comparable to
the results of DSPot (successful in 65% of the cases) and Small-Amp
(successful in 60% of the cases). We collected qualitative evidence from the
cases where Ampyfier failed to strengthen the test suite, deriving lessons
learned and sketching areas for further improvement. Despite these
shortcoming, we conclude that test amplification is feasible for one of the
most popular programming languages in use today.

## Acknowledgments

This work is supported by (a) the Fonds de la Recherche Scientifique-FNRS and
the Fonds Wetenschappelijk Onderzoek - Vlaanderen (FWO) under EOS Project
30446992 SECO-ASSIST (b) Flanders Make vzw, the strategic research centre for
the manufacturing industry.

## References

  * 1 Zhu H, Hall PA, May JH. Software unit test coverage and adequacy. Acm computing surveys (csur) 1997; 29(4): 366–427.
  * 2 Papadakis M, Kintis M, Zhang J, Jia Y, Traon YL, Harman M. Mutation Testing Advances: An Analysis and Survey. Advances in Computers 2019; 112: 275-378.  doi: 10.1016/bs.adcom.2018.03.015
  * 3 Lu ZX, Vercammen S, Demeyer S. Semi-automatic test case expansion for mutation testing. In: 2020 IEEE Workshop on Validation, Analysis and Evolution of Software Tests (VST)IEEE. ; 2020: 1–7.
  * 4 Fraser G, Arcuri A. Evosuite: automatic test suite generation for object-oriented software. In: Proceedings of the 19th ACM SIGSOFT symposium and the 13th European conference on Foundations of software engineering; 2011: 416–419.
  * 5 Danglot B, Vera-Perez O, Yu Z, Zaidman A, Monperrus M, Baudry B. A snowballing literature study on test amplification. Journal of Systems and Software 2019; 157: 110398.
  * 6 Baudry B, Allier S, Rodriguez-Cancio M, Monperrus M. DSpot: Test amplification for automatic assessment of computational diversity. arXiv preprint arXiv:1503.05807 2015\.
  * 7 Danglot B, Vera-Pérez OL, Baudry B, Monperrus M. Automatic test improvement with DSpot: a study with ten mature open-source projects. Empirical Software Engineering 2019; 24(4): 2603–2635.
  * 8 Abdi M, Rocha H, Demeyer S. Test amplification in the pharo smalltalk ecosystem. In: Proceedings IWST 2019 International Workshop on Smalltalk Technologies. ESUG; 2019.
  * 9 Abdi M, Rocha H, Demeyer S, Bergel A. Small-Amp: Test Amplification in a Dynamically Typed Language. arXiv preprint arXiv:2108.05663 2021\.
  * 10 Srinath K. Python–the fastest growing programming language. International Research Journal of Engineering and Technology 2017; 4(12): 354–357.
  * 11 Lukasczyk S, Kroiß F, Fraser G. Automated Unit Test Generation for Python. In: International Symposium on Search Based Software EngineeringSpringer. ; 2020: 9–24.
  * 12 Laffra C. Auger: Automated Unittest Generation for Python. 2016.
  * 13 Van Rossum G, others . Python Programming Language.. In: USENIX annual technical conference. 41. ; 2007: 36.
  * 14 Xie T. Augmenting automatically generated unit-test suites with regression oracle checking. In: European Conference on Object-Oriented ProgrammingSpringer. ; 2006: 380–403.
  * 15 Tonella P. Evolutionary testing of classes. Proceedings of the 2004 ACM SIGSOFT international symposium on Software testing and analysis - ISSTA ’04 2004\.  doi: 10.1145/1007512.1007528
  * 16 Costiou S, Aranega V, Denker M. Sub-method, partial behavioral reflection with Reflectivity: Looking back on 10 years of use. arXiv preprint arXiv:2002.06182 2020\.
  * 17 inspect — Inspect live objects — Python 3.9.7 documentation. https://docs.python.org/3/library/inspect.html; .  (Accessed on 09/13/2021).
  * 18 Knupp J. Writing Idiomatic Python 3.  Jeff Knupp; 1st edition (November 30, 2013) .  2013\.
  * 19 Pacheco C, Lahiri SK, Ernst MD, Ball T. Feedback-directed random test generation. In: 29th International Conference on Software Engineering (ICSE’07)IEEE. ; 2007: 75–84.
  * 20 Python Software Foundation . typing - Support for type hints - Python 3.9.7 documentation. https://docs.python.org/3/library/typing.html; 2021.  [Online; accessed 14-September-2021].
  * 21 Petrović G, Ivanković M. State of Mutation Testing at Google. In: Proceedings of the 40th International Conference on Software Engineering: Software Engineering in PracticeICSE-SEIP ’18. Association for Computing Machinery; 2018; New York, NY, USA: 163–171
  * 22 Nijkamp N, Brandt C, Zaidman A. Naming Amplified Tests Based on Improved Coverage. In: Proceedings SCAM 2021 (IEEE International Working Conference on Source Code Analysis and Manipulation; 2021: xx–xx.
  * 23 Person S, Dwyer MB, Elbaum S, Pǎsǎreanu CS. Differential symbolic execution. In: Proceedings of the 16th ACM SIGSOFT International Symposium on Foundations of software engineering; 2008: 226–237.
  * 24 Carzaniga A, Goffi A, Gorla A, Mattavelli A, Pezzè M. Cross-checking oracles from intrinsic software redundancy. In: Proceedings of the 36th International Conference on Software Engineering; 2014: 931–942.