Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Unit test marking #104

Closed
wants to merge 6 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions pytest.ini
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
[pytest]
testpaths = tests
adopts = -m "not slow"
markers =
precision_sensitive: Tests that are sensitive to the numerical precision used in calculations.
integration: Tests to determine if independent units of code work together. Typically carried out after significant changes.
slow: Tests that take longer than 1 second to run.
51 changes: 50 additions & 1 deletion tests/test_covariance_builder.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,63 @@
import pickle
import pyccl as ccl
import pymaster as nmt

from unittest.mock import MagicMock
from tjpcov.covariance_builder import CovarianceBuilder
from scipy.linalg import block_diag

INPUT_YML = "./tests/data/conf_covariance_builder_minimal.yaml"
OUTDIR = "tests/tmp/"


def test_no_config_throws():
mock_builder = MagicMock(CovarianceBuilder)
Copy link
Contributor

Choose a reason for hiding this comment

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

What magic is MagicMock doing?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I use unittest.mock here to test the logic in the base class without needing to instantiate any concrete implementations. This is preferable because then we aren't implicitly testing something else.

MagicMock is a regular Mock that also allows you to mock dunder methods (e.g. __new__). In this case the added mocking allows us to directly call the __init__ function on the base class.


with pytest.raises(TypeError):
CovarianceBuilder.__init__(mock_builder, None)

with pytest.raises(TypeError):
CovarianceBuilder.__init__(mock_builder)


def test_invalid_config_throws():
mock_builder = MagicMock(CovarianceBuilder)

with pytest.raises(FileNotFoundError):
CovarianceBuilder.__init__(mock_builder, "")

with pytest.raises(ValueError):
CovarianceBuilder.__init__(mock_builder, {})


def test_config_values_read():
mock_builder = MagicMock(CovarianceBuilder)
config = {
"tjpcov": {
"IA": "IA_Value",
"mask_file": "mask_file_value",
"mask_names": "mask_names_value",
"nside": "nside_value",
}
}

CovarianceBuilder.__init__(mock_builder, config)

assert mock_builder.IA == "IA_Value"
assert mock_builder.mask_files == "mask_file_value"
assert mock_builder.mask_names == "mask_names_value"
assert mock_builder.nside == "nside_value"
assert mock_builder.config == config
assert mock_builder.cov is None
assert mock_builder.cosmo is None
assert mock_builder.nbpw is None
assert mock_builder.Ngal == {}
assert mock_builder.sigma_e == {}
# Need to implement __eq__ and __hash__ and a bit of refactoring in
# CovarianceIO to make this work
# assert mock_builder.io == CovarianceIO(config)
assert mock_builder.io.config == config


def setup_module():
os.makedirs(OUTDIR, exist_ok=True)

Expand Down
4 changes: 4 additions & 0 deletions tests/test_covariance_calculator.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ def test_get_covariance_classes(mock_cov_calc):
cc.get_covariance_classes()


@pytest.mark.slow
def test_get_covariance(mock_cov_calc):
cov = mock_cov_calc.get_covariance() + 1e-100

Expand All @@ -67,6 +68,7 @@ def test_get_covariance(mock_cov_calc):
assert np.max(np.abs(cov / cov2 - 1) < 1e-10)


@pytest.mark.slow
def test_get_covariance_terms(mock_cov_calc):
cov_terms = mock_cov_calc.get_covariance_terms()

Expand All @@ -77,6 +79,8 @@ def test_get_covariance_terms(mock_cov_calc):
assert np.all(cov_terms["SSC"] == cov_ssc)


@pytest.mark.slow
@pytest.mark.precision_sensitive
def test_create_sacc_cov(mock_cov_calc):
cov = mock_cov_calc.get_covariance() + 1e-100

Expand Down
10 changes: 10 additions & 0 deletions tests/test_covariance_clusters.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ def test_load_from_cosmology(mock_covariance_gauss: CovarianceClusterCounts):
assert mock_covariance_gauss.cosmo == cosmo


@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"z, ref_val",
[
Expand All @@ -168,6 +169,7 @@ def test_integral_mass_no_bias(
assert test == pytest.approx(ref_val, rel=1e-3)


@pytest.mark.precision_sensitive
def test_double_bessel_integral(
mock_covariance_gauss: CovarianceClusterCounts,
):
Expand All @@ -176,12 +178,15 @@ def test_double_bessel_integral(
assert test == pytest.approx(ref, rel=1e-3)


@pytest.mark.slow
@pytest.mark.precision_sensitive
def test_shot_noise(mock_covariance_gauss: ClusterCountsGaussian):
ref = 63973.635143644424
test = mock_covariance_gauss.shot_noise(0, 0)
assert test == pytest.approx(ref, rel=1e-3)


@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"z, reference_val",
[
Expand All @@ -196,6 +201,7 @@ def test_integral_mass(
assert test == pytest.approx(reference_val, rel=1e-3)


@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"z, reference_val",
[
Expand All @@ -211,6 +217,7 @@ def test_integral_mass_no_mproxy(
assert test == pytest.approx(reference_val, rel=1e-1)


@pytest.mark.precision_sensitive
def test_mass_richness(mock_covariance_gauss: CovarianceClusterCounts):
reference_min = 0.0009528852621284171

Expand All @@ -221,6 +228,7 @@ def test_mass_richness(mock_covariance_gauss: CovarianceClusterCounts):
assert np.sum(test_min) == pytest.approx(reference_min)


@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"z_i, reference_val",
[
Expand Down Expand Up @@ -265,6 +273,8 @@ def test_cov_gaussian_zero_offdiagonal(
assert cov_10_gauss == 0


@pytest.mark.slow
@pytest.mark.precision_sensitive
def test_cov_nxn(
mock_covariance_gauss: ClusterCountsGaussian,
mock_covariance_ssc: ClusterCountsSSC,
Expand Down
3 changes: 3 additions & 0 deletions tests/test_covariance_fourier_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ def get_nmt_bin(lmax=95):
return nmt.NmtBin.from_edges(bpw_edges[:-1], bpw_edges[1:])


@pytest.mark.precision_sensitive
def test_build_matrix_from_blocks():
class CFT(CovarianceFourierTester):
def get_covariance_block(self, trs1, trs2):
Expand All @@ -85,6 +86,7 @@ def get_covariance_block(self, trs1, trs2):
assert np.max(np.abs(cov / cov2 - 1)) < 1e-10


@pytest.mark.precision_sensitive
def test__get_covariance_block_for_sacc():
# Test with matrices ordered as in C
class CFT(CovarianceFourierTester):
Expand Down Expand Up @@ -208,6 +210,7 @@ def test_get_tracer_comb_ncell(mock_cov_fourier):
)


@pytest.mark.precision_sensitive
def test_get_tracer_info(mock_cov_fourier):
ccl_tracers1, tracer_noise1 = mock_cov_fourier.get_tracer_info()
(
Expand Down
14 changes: 13 additions & 1 deletion tests/test_covariance_fourier_gaussian_nmt.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def cov_fg_nmt():

# Useful functions
def get_config(fname):
return CovarianceIO._parse(fname)
return CovarianceIO.get_dict_from_yaml(fname)


def assert_chi2(s, tracer_comb1, tracer_comb2, cov, cov_bm, threshold):
Expand Down Expand Up @@ -343,6 +343,7 @@ def _get_covariance_block_for_sacc(
)


@pytest.mark.precision_sensitive
def test_get_cl_for_cov(cov_fg_nmt):
# We just need to test for one case as the function will complain if the
# Cell inputted has the wrong shape
Expand Down Expand Up @@ -402,6 +403,8 @@ def test_get_cl_for_cov(cov_fg_nmt):
)


@pytest.mark.slow
@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"tracer_comb1,tracer_comb2",
[
Expand Down Expand Up @@ -565,6 +568,7 @@ def test_get_covariance_block(tracer_comb1, tracer_comb2):
)


@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"tracer_comb1,tracer_comb2",
[
Expand Down Expand Up @@ -660,6 +664,7 @@ def test_get_covariance_block_cache(cov_fg_nmt, tracer_comb1, tracer_comb2):
assert_chi2(s, tracer_comb1, tracer_comb2, cov, cov_bm, 1e-6)


@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"kwargs",
[{}, {"l_toeplitz": 10, "l_exact": 10, "dl_band": 10, "n_iter": 0}],
Expand Down Expand Up @@ -767,6 +772,7 @@ def test_get_covariance_workspace(cov_fg_nmt, kwargs):
# assert not os.path.isfile(fname)


@pytest.mark.precision_sensitive
@pytest.mark.parametrize("nmt_conf", [{}, {"n_iter": 0}])
def test_get_fields_dict(cov_fg_nmt, nmt_conf):
tr = get_tracers_dict_for_cov()
Expand Down Expand Up @@ -965,6 +971,7 @@ def get_data_types(self):
assert nell == cov_fg_nmt.get_nell(nside=NSIDE)


@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"kwargs",
[{}, {"l_toeplitz": 10, "l_exact": 10, "dl_band": 10, "n_iter": 0}],
Expand Down Expand Up @@ -1028,6 +1035,7 @@ def test_get_workspace(cov_fg_nmt, kwargs):
# assert not os.path.isfile(fname)


@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"kwargs",
[{}, {"l_toeplitz": 10, "l_exact": 10, "dl_band": 10, "n_iter": 0}],
Expand Down Expand Up @@ -1120,6 +1128,8 @@ def test_get_workspace_dict(cov_fg_nmt, kwargs):
w2 = cov_fg_nmt.get_workspaces_dict(tracers, None, cache=cache, **kwargs)


@pytest.mark.slow
@pytest.mark.precision_sensitive
@pytest.mark.flaky(reruns=5, reruns_delay=1)
def test_full_covariance_benchmark():
config = get_config(INPUT_YML)
Expand Down Expand Up @@ -1200,6 +1210,8 @@ def test_full_covariance_benchmark():
assert np.max(np.abs(cov / cov2 - 1)) < 1e-10


@pytest.mark.slow
@pytest.mark.precision_sensitive
def test_txpipe_like_input():
# We don't need to pass the bins because we have provided the workspaces
# through the cache in the configuration file
Expand Down
4 changes: 4 additions & 0 deletions tests/test_covariance_fourier_ssc.py
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,8 @@ def test_smoke():
FourierSSCHaloModel(INPUT_YML_SSC)


@pytest.mark.slow
@pytest.mark.precision_sensitive
@pytest.mark.parametrize(
"tracer_comb1,tracer_comb2",
[
Expand Down Expand Up @@ -243,6 +245,8 @@ def test_get_covariance_block(cov_fssc, tracer_comb1, tracer_comb2):
assert np.all(covf["cov"] == cov_ssc_zb)


@pytest.mark.slow
@pytest.mark.precision_sensitive
def test_get_covariance_block_WL_benchmark(cov_fssc):
# Based on CCL benchmark test in benchmarks/test_covariances.py
#
Expand Down
3 changes: 3 additions & 0 deletions tests/test_covariance_gaussian_fsky.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ def test_Fourier_get_binning_info(cov_fg_fsky):
cov_fg_fsky.get_binning_info("log")


@pytest.mark.slow
def test_Fourier_get_covariance_block(cov_fg_fsky, mock_cosmo):
# Test made independent of pickled objects
tracer_comb1 = ("lens0", "lens0")
Expand Down Expand Up @@ -129,6 +130,7 @@ def test_Fourier_get_covariance_block(cov_fg_fsky, mock_cosmo):
np.testing.assert_allclose(cov2, cov)


@pytest.mark.slow
@pytest.mark.parametrize(
"tracer_comb1",
[
Expand Down Expand Up @@ -159,6 +161,7 @@ def test_Real_get_fourier_block(
assert np.all(cov == cov2 / norm)


@pytest.mark.slow
def test_smoke_get_covariance(cov_fg_fsky, cov_rg_fsky):
# Check that we can get the full covariance
cov_fg_fsky.get_covariance()
Expand Down
Loading
Loading