Repository: kornia/kornia
Pull request: fix tests float16 module losses
#### Changes
<!-- Please include a summary of the change and which issue is fixed. -->
<!-- Please also include relevant motivation and context. -->
<!-- List any dependencies that are required for this change. -->

Fixes #1805


#### Type of change
<!-- Please delete options that are not relevant. -->
- [ ] 📚  Documentation Update
- [ ] 🧪 Tests Cases
- [ ] 🐞 Bug fix (non-breaking change which fixes an issue)
- [x] 🔬 New feature (non-breaking change which adds functionality)
- [ ] 🚨 Breaking change (fix or feature that would cause existing functionality to not work as expected)
- [ ] 📝 This change requires a documentation update


#### Checklist

- [ ] My code follows the style guidelines of this project
- [ ] I have performed a self-review of my own code
- [ ] I have commented my code, particularly in hard-to-understand areas
- [ ] I have made corresponding changes to the documentation
- [ ] My changes generate no new warnings
- [ ] Did you update CHANGELOG in case of a major change?

#### Progress

Fixed all errors when calling `pytest test/losses -v --dtype=float16 --device=cuda`, most caused by using float type in assert_close instead of torch.float.

I continue to think about using BaseTester and the mechanism that chooses the tolerance.


Problem statement:
Configure `rtol` and `atol` parameters to pass tests on the `losses` module
## 🚀 Feature

When running tests using `float16` and `cuda` in `losses` module, errors occurs.

 `pytest test/losses -v --dtype=float16 --device=cuda`
 
 ```========================================================================================= short test summary info ==========================================================================================
FAILED test/losses/test_losses.py::TestDivergenceLoss::test_js_div_loss_2d[cuda-float16-input2-target2-0.346574] - AssertionError: Scalars are not close!
FAILED test/losses/test_losses.py::TestDivergenceLoss::test_js_div_loss_2d[cuda-float16-input3-target3-0.346574] - AssertionError: Scalars are not close!
FAILED test/losses/test_losses.py::TestDivergenceLoss::test_noncontiguous_js[cuda-float16-input2-target2-0.346574] - AssertionError: Scalars are not close!
FAILED test/losses/test_losses.py::TestDivergenceLoss::test_noncontiguous_js[cuda-float16-input3-target3-0.346574] - AssertionError: Scalars are not close!
FAILED test/losses/test_losses.py::TestTotalVariation::test_tv_on_4d[cuda-float16-input0-expected0] - AssertionError: Tensor-likes are not close!
FAILED test/losses/test_losses.py::TestTotalVariation::test_tv_on_4d[cuda-float16-input1-expected1] - AssertionError: Tensor-likes are not close!
```

If you use `float16`, these errors not occurs. It seems they are caused by the fact that the parameters `rtol` and `atol` are not configured.

Example of error description:
```
E       AssertionError: Tensor-likes are not close!
E
E       Mismatched elements: 1 / 3 (33.3%)
E       Greatest absolute difference: 0.001953125 at index 2 (up to 0.0001 allowed)
E       Greatest relative difference: 0.0008613264427217916 at index 2 (up to 0.0001 allowed)
```

I suggest choosing default thresholds for `rtol` and `atol` in testing api to pass all these tests.

### Environment

- PyTorch version: 1.10.1+cu113
- Python version: 3.6.9
- CUDA Version: 11.6

Open to PR :)

Hints from issue discussion:
@MrShevan probably need a mechanism in the Test class that chooses the tolerance based on the precision ? 
I started this initiative some time ago but never had the chance to implement it across the library
https://github.com/kornia/kornia/blob/master/kornia/testing/__init__.py#L78

worth to explore adding that functionality there

Commit message: add `assert_close` method to BaseTester

Patch to review:
diff --git a/kornia/testing/__init__.py b/kornia/testing/__init__.py
index 426518dd19..c82bbfdb0d 100644
--- a/kornia/testing/__init__.py
+++ b/kornia/testing/__init__.py
@@ -76,30 +76,44 @@ def create_random_fundamental_matrix(batch_size, std_val=1e-3):
 
 
 class BaseTester(ABC):
+    DTYPE_PRECISIONS = {torch.float16: (1e-2, 1e-3), torch.float32: (1e-4, 1e-4), torch.float64: (1e-5, 1e-8)}
+
     @abstractmethod
-    def test_smoke(self):
+    def test_smoke(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_exception(self):
+    def test_exception(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_cardinality(self):
+    def test_cardinality(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_jit(self):
+    def test_jit(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_gradcheck(self):
+    def test_gradcheck(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_module(self):
+    def test_module(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
+    def assert_close(self, actual: torch.Tensor, expected: torch.Tensor, low_tolerance: bool = False) -> None:
+        if low_tolerance:
+            rtol, atol = 1e-2, 1e-2
+        elif 'xla' in actual.device.type or 'xla' in expected.device.type:
+            rtol, atol = 1e-2, 1e-2
+        else:
+            actual_rtol, actual_atol = self.DTYPE_PRECISIONS.get(actual.dtype, (0.0, 0.0))
+            expected_rtol, expected_atol = self.DTYPE_PRECISIONS.get(expected.dtype, (0.0, 0.0))
+            rtol, atol = max(actual_rtol, expected_rtol), max(actual_atol, expected_atol)
+
+        return _assert_close(actual, expected, rtol=rtol, atol=atol)
+
 
 def cartesian_product_of_parameters(**possible_parameters):
     """Create cartesian product of given parameters."""
@@ -163,7 +177,7 @@ def assert_close(
 except ImportError:
     # Partial backport of torch.testing.assert_close for torch<1.9
     # TODO: remove this branch if kornia relies on torch>=1.9
-    from torch.testing import assert_allclose as _assert_allclose
+    from torch.testing import assert_allclose as _assert_close
 
     class UsageError(Exception):
         pass
@@ -177,7 +191,7 @@ def assert_close(
         **kwargs: Any,
     ) -> None:
         try:
-            return _assert_allclose(actual, expected, rtol=rtol, atol=atol, **kwargs)
+            return _assert_close(actual, expected, rtol=rtol, atol=atol, **kwargs)
         except ValueError as error:
             raise UsageError(str(error)) from error
 
diff --git a/test/augmentation/test_augmentation.py b/test/augmentation/test_augmentation.py
index c82112b168..004ceb3cf9 100644
--- a/test/augmentation/test_augmentation.py
+++ b/test/augmentation/test_augmentation.py
@@ -43,7 +43,7 @@
 from kornia.augmentation._2d.base import AugmentationBase2D
 from kornia.constants import Resample, pi
 from kornia.geometry import transform_points
-from kornia.testing import BaseTester, assert_close, default_with_one_parameter_changed
+from kornia.testing import BaseTester, default_with_one_parameter_changed
 from kornia.utils import create_meshgrid
 from kornia.utils.helpers import _torch_inverse_cast
 
@@ -200,10 +200,10 @@ def _test_random_p_1_implementation(self, input_tensor, expected_output, params,
 
         # Output should match
         assert output.shape == expected_output.shape
-        assert_close(output, expected_output.to(device=self.device, dtype=self.dtype), atol=1e-4, rtol=1e-4)
+        self.assert_close(output, expected_output.to(device=self.device, dtype=self.dtype))
         if expected_transformation is not None:
             transform = augmentation.transform_matrix
-            assert_close(transform, expected_transformation, atol=1e-4, rtol=1e-4)
+            self.assert_close(transform, expected_transformation)
 
     def _test_module_implementation(self, params):
         augmentation = self._create_augmentation_from_params(**params, p=0.5)
@@ -224,8 +224,8 @@ def _test_module_implementation(self, params):
 
         assert out1.shape == out_sequence.shape
         assert transform.shape == transform_sequence.shape
-        assert_close(out2, out_sequence, atol=1e-4, rtol=1e-4)
-        assert_close(transform, transform_sequence, atol=1e-4, rtol=1e-4)
+        self.assert_close(out2, out_sequence)
+        self.assert_close(transform, transform_sequence)
 
     def _test_inverse_coordinate_check_implementation(self, params):
         torch.manual_seed(42)
@@ -254,7 +254,7 @@ def _test_inverse_coordinate_check_implementation(self, params):
         output_values = output[0, :, output_indices[:, 1][value_mask], output_indices[:, 0][value_mask]]
         input_values = input_tensor[0, :, input_indices[:, 1][value_mask], input_indices[:, 0][value_mask]]
 
-        assert_close(output_values, input_values, atol=1e-4, rtol=1e-4)
+        self.assert_close(output_values, input_values)
 
     def _test_gradcheck_implementation(self, params):
         input_tensor = torch.rand((3, 5, 5), device=self.device, dtype=self.dtype)  # 3 x 3
@@ -820,7 +820,7 @@ def test_gradcheck(self, device, dtype):
         assert gradcheck(RandomHorizontalFlip(p=1.0), (input,), raise_exception=True)
 
 
-class TestRandomVerticalFlip:
+class TestRandomVerticalFlip(BaseTester):
 
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
@@ -851,13 +851,13 @@ def test_random_vflip(self, device, dtype):
             [[[1.0, 0.0, 0.0], [0.0, 1.0, 0.0], [0.0, 0.0, 1.0]]], device=device, dtype=dtype
         )  # 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
-        assert_close(f1(input), input, atol=1e-4, rtol=1e-4)
-        assert_close(f1.transform_matrix, identity, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
+        self.assert_close(f1(input), input)
+        self.assert_close(f1.transform_matrix, identity)
 
-        assert_close(f.inverse(expected), input, atol=1e-4, rtol=1e-4)
-        assert_close(f1.inverse(input), input, atol=1e-4, rtol=1e-4)
+        self.assert_close(f.inverse(expected), input)
+        self.assert_close(f1.inverse(input), input)
 
     def test_batch_random_vflip(self, device, dtype):
 
@@ -884,9 +884,9 @@ def test_batch_random_vflip(self, device, dtype):
         expected_transform = expected_transform.repeat(5, 1, 1)  # 5 x 3 x 3
         identity = identity.repeat(5, 1, 1)  # 5 x 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
-        assert_close(f.inverse(expected), input, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
+        self.assert_close(f.inverse(expected), input)
 
     def test_same_on_batch(self, device, dtype):
         f = RandomVerticalFlip(p=0.5, same_on_batch=True)
@@ -909,8 +909,8 @@ def test_sequential(self, device, dtype):
 
         expected_transform_1 = expected_transform @ expected_transform
 
-        assert_close(f(input), input, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform_1, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), input)
+        self.assert_close(f.transform_matrix, expected_transform_1)
 
     def test_random_vflip_coord_check(self, device, dtype):
 
@@ -961,8 +961,33 @@ def test_random_vflip_coord_check(self, device, dtype):
             == input[..., input_coordinates[0, 1, :], input_coordinates[0, 0, :]]
         ).all()
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_gradcheck(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
 
-class TestColorJiggle:
+class TestColorJiggle(BaseTester):
 
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
@@ -985,8 +1010,8 @@ def test_color_jiggle(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0)  # 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_color_jiggle_batch(self, device, dtype):
         f = ColorJiggle()
@@ -996,8 +1021,8 @@ def test_color_jiggle_batch(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0).expand((2, 3, 3))  # 2 x 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_same_on_batch(self, device, dtype):
         f = ColorJiggle(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.1, same_on_batch=True)
@@ -1034,7 +1059,7 @@ def test_random_brightness(self, device, dtype):
 
         expected = self._get_expected_brightness(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_brightness_tuple(self, device, dtype):
         torch.manual_seed(42)
@@ -1047,7 +1072,7 @@ def test_random_brightness_tuple(self, device, dtype):
 
         expected = self._get_expected_brightness(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def _get_expected_contrast(self, device, dtype):
         return torch.tensor(
@@ -1078,7 +1103,7 @@ def test_random_contrast(self, device, dtype):
 
         expected = self._get_expected_contrast(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_contrast_list(self, device, dtype):
         torch.manual_seed(42)
@@ -1091,7 +1116,7 @@ def test_random_contrast_list(self, device, dtype):
 
         expected = self._get_expected_contrast(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def _get_expected_saturation(self, device, dtype):
         return torch.tensor(
@@ -1129,7 +1154,7 @@ def test_random_saturation(self, device, dtype):
         input = input.repeat(2, 1, 1, 1)  # 2 x 3 x 3
 
         expected = self._get_expected_saturation(device, dtype)
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_saturation_tensor(self, device, dtype):
         torch.manual_seed(42)
@@ -1150,7 +1175,7 @@ def test_random_saturation_tensor(self, device, dtype):
 
         expected = self._get_expected_saturation(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_saturation_tuple(self, device, dtype):
         torch.manual_seed(42)
@@ -1171,7 +1196,7 @@ def test_random_saturation_tuple(self, device, dtype):
 
         expected = self._get_expected_saturation(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def _get_expected_hue(self, device, dtype):
         return torch.tensor(
@@ -1210,7 +1235,7 @@ def test_random_hue(self, device, dtype):
 
         expected = self._get_expected_hue(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_hue_list(self, device, dtype):
         torch.manual_seed(42)
@@ -1231,7 +1256,7 @@ def test_random_hue_list(self, device, dtype):
 
         expected = self._get_expected_hue(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_sequential(self, device, dtype):
 
@@ -1243,8 +1268,8 @@ def test_sequential(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0)  # 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_color_jitter_batch_sequential(self, device, dtype):
         f = AugmentationSequential(ColorJiggle(), ColorJiggle())
@@ -1254,17 +1279,37 @@ def test_color_jitter_batch_sequential(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0).expand((2, 3, 3))  # 2 x 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_gradcheck(self, device, dtype):
         input = torch.rand((3, 5, 5), device=device, dtype=dtype).unsqueeze(0)  # 3 x 3
         input = utils.tensor_to_gradcheck_var(input)  # to var
         assert gradcheck(ColorJiggle(p=1.0), (input,), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
 
-class TestColorJitter:
+
+class TestColorJitter(BaseTester):
 
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
@@ -1287,8 +1332,8 @@ def test_color_jitter(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0)  # 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_color_jitter_batch(self, device, dtype):
         f = ColorJitter()
@@ -1298,8 +1343,8 @@ def test_color_jitter_batch(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0).expand((2, 3, 3))  # 2 x 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_same_on_batch(self, device, dtype):
         f = ColorJitter(brightness=0.5, contrast=0.5, saturation=0.5, hue=0.1, same_on_batch=True)
@@ -1336,7 +1381,7 @@ def test_random_brightness(self, device, dtype):
 
         expected = self._get_expected_brightness(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_brightness_tuple(self, device, dtype):
         torch.manual_seed(42)
@@ -1349,7 +1394,7 @@ def test_random_brightness_tuple(self, device, dtype):
 
         expected = self._get_expected_brightness(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def _get_expected_contrast(self, device, dtype):
         return torch.tensor(
@@ -1380,7 +1425,7 @@ def test_random_contrast(self, device, dtype):
 
         expected = self._get_expected_contrast(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_contrast_list(self, device, dtype):
         torch.manual_seed(42)
@@ -1393,7 +1438,7 @@ def test_random_contrast_list(self, device, dtype):
 
         expected = self._get_expected_contrast(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def _get_expected_saturation(self, device, dtype):
         return torch.tensor(
@@ -1431,7 +1476,7 @@ def test_random_saturation(self, device, dtype):
         input = input.repeat(2, 1, 1, 1)  # 2 x 3 x 3
 
         expected = self._get_expected_saturation(device, dtype)
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_saturation_tensor(self, device, dtype):
         torch.manual_seed(42)
@@ -1452,7 +1497,7 @@ def test_random_saturation_tensor(self, device, dtype):
 
         expected = self._get_expected_saturation(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_saturation_tuple(self, device, dtype):
         torch.manual_seed(42)
@@ -1473,7 +1518,7 @@ def test_random_saturation_tuple(self, device, dtype):
 
         expected = self._get_expected_saturation(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def _get_expected_hue(self, device, dtype):
         return torch.tensor(
@@ -1512,7 +1557,7 @@ def test_random_hue(self, device, dtype):
 
         expected = self._get_expected_hue(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_random_hue_list(self, device, dtype):
         torch.manual_seed(42)
@@ -1533,7 +1578,7 @@ def test_random_hue_list(self, device, dtype):
 
         expected = self._get_expected_hue(device, dtype)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_sequential(self, device, dtype):
 
@@ -1545,8 +1590,8 @@ def test_sequential(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0)  # 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_color_jitter_batch_sequential(self, device, dtype):
         f = AugmentationSequential(ColorJitter(), ColorJitter())
@@ -1556,17 +1601,37 @@ def test_color_jitter_batch_sequential(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0).expand((2, 3, 3))  # 2 x 3 x 3
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_gradcheck(self, device, dtype):
         input = torch.rand((3, 5, 5), device=device, dtype=dtype).unsqueeze(0)  # 3 x 3
         input = utils.tensor_to_gradcheck_var(input)  # to var
         assert gradcheck(ColorJitter(p=1.0), (input,), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
 
-class TestRectangleRandomErasing:
+class TestRectangleRandomErasing(BaseTester):
     @pytest.mark.parametrize("erase_scale_range", [(0.001, 0.001), (1.0, 1.0)])
     @pytest.mark.parametrize("aspect_ratio_range", [(0.1, 0.1), (10.0, 10.0)])
     @pytest.mark.parametrize("batch_shape", [(1, 4, 8, 15), (2, 3, 11, 7)])
@@ -1606,8 +1671,33 @@ def test_gradcheck(self, device, dtype):
         input = utils.tensor_to_gradcheck_var(input)  # to var
         assert gradcheck(rand_rec, (input, rect_params), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
 
-class TestRandomGrayscale:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+
+class TestRandomGrayscale(BaseTester):
 
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
@@ -1625,7 +1715,7 @@ def test_random_grayscale(self, device, dtype):
 
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0)  # 3 x 3
         f(input)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_same_on_batch(self, device, dtype):
         f = RandomGrayscale(p=0.5, same_on_batch=True)
@@ -1696,7 +1786,7 @@ def test_opencv_true(self, device, dtype):
         )
 
         img_gray = RandomGrayscale(p=1.0)(data)
-        assert_close(img_gray, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(img_gray, expected)
 
     def test_opencv_false(self, device, dtype):
         data = torch.tensor(
@@ -1732,7 +1822,7 @@ def test_opencv_false(self, device, dtype):
         expected = data
 
         img_gray = RandomGrayscale(p=0.0)(data)
-        assert_close(img_gray, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(img_gray, expected)
 
     def test_opencv_true_batch(self, device, dtype):
         data = torch.tensor(
@@ -1795,7 +1885,7 @@ def test_opencv_true_batch(self, device, dtype):
         expected = expected.unsqueeze(0).repeat(4, 1, 1, 1)
 
         img_gray = RandomGrayscale(p=1.0)(data)
-        assert_close(img_gray, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(img_gray, expected)
 
     def test_opencv_false_batch(self, device, dtype):
         data = torch.tensor(
@@ -1830,7 +1920,7 @@ def test_opencv_false_batch(self, device, dtype):
         expected = data
 
         img_gray = RandomGrayscale(p=0.0)(data)
-        assert_close(img_gray, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(img_gray, expected)
 
     def test_random_grayscale_sequential_batch(self, device, dtype):
         f = AugmentationSequential(RandomGrayscale(p=0.0), RandomGrayscale(p=0.0))
@@ -1841,8 +1931,8 @@ def test_random_grayscale_sequential_batch(self, device, dtype):
         expected_transform = torch.eye(3, device=device, dtype=dtype).unsqueeze(0).expand((2, 3, 3))  # 2 x 3 x 3
         expected_transform = expected_transform.to(device)
 
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_gradcheck(self, device, dtype):
         input = torch.rand((3, 5, 5), device=device, dtype=dtype)  # 3 x 3
@@ -1850,8 +1940,28 @@ def test_gradcheck(self, device, dtype):
         assert gradcheck(RandomGrayscale(p=1.0), (input,), raise_exception=True)
         assert gradcheck(RandomGrayscale(p=0.0), (input,), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
 
-class TestCenterCrop:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+
+class TestCenterCrop(BaseTester):
     def test_no_transform(self, device, dtype):
         inp = torch.rand(1, 2, 4, 4, device=device, dtype=dtype)
         out = CenterCrop(2)(inp)
@@ -1891,15 +2001,40 @@ def test_crop_modes(self, device, dtype):
 
         op2 = CenterCrop(size=(2, 2), cropping_mode='slice')
 
-        assert_close(out, op2(img, op1._params))
+        self.assert_close(out, op2(img, op1._params))
 
     def test_gradcheck(self, device, dtype):
         input = torch.rand(1, 2, 3, 4, device=device, dtype=dtype)
         input = utils.tensor_to_gradcheck_var(input)  # to var
         assert gradcheck(CenterCrop(3), (input,), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
 
-class TestRandomRotation:
+class TestRandomRotation(BaseTester):
 
     torch.manual_seed(0)  # for random reproductibility
 
@@ -1948,8 +2083,8 @@ def test_random_rotation(self, device, dtype):
         )  # 1 x 3 x 3
 
         out = f(input)
-        assert_close(out, expected, rtol=1e-6, atol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, rtol=1e-6, atol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_batch_random_rotation(self, device, dtype):
 
@@ -1998,8 +2133,8 @@ def test_batch_random_rotation(self, device, dtype):
         input = input.repeat(2, 1, 1, 1)  # 5 x 3 x 3 x 3
 
         out = f(input)
-        assert_close(out, expected, rtol=1e-4, atol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, rtol=1e-4, atol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_same_on_batch(self, device, dtype):
         f = RandomRotation(degrees=40, same_on_batch=True)
@@ -2041,8 +2176,8 @@ def test_sequential(self, device, dtype):
         )  # 1 x 3 x 3
 
         out = f(input)
-        assert_close(out, expected, rtol=1e-4, atol=1e-4)
-        assert_close(f.transform_matrix, expected_transform, rtol=1e-4, atol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(f.transform_matrix, expected_transform)
 
     def test_gradcheck(self, device, dtype):
 
@@ -2052,8 +2187,28 @@ def test_gradcheck(self, device, dtype):
         input = utils.tensor_to_gradcheck_var(input)  # to var
         assert gradcheck(RandomRotation(degrees=(15.0, 15.0), p=1.0), (input,), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
 
-class TestRandomCrop:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+
+class TestRandomCrop(BaseTester):
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
     @pytest.mark.xfail(reason="might fail under windows OS due to printing preicision.")
@@ -2075,14 +2230,14 @@ def test_no_padding(self, device, dtype):
         torch.manual_seed(0)
         out2 = rc(inp.squeeze())
 
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(out2, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(out2, expected)
         torch.manual_seed(0)
         inversed = torch.tensor([[[[0.0, 0.0, 0.0], [3.0, 4.0, 5.0], [6.0, 7.0, 8.0]]]], device=device, dtype=dtype)
         aug = RandomCrop(size=(2, 3), padding=None, align_corners=True, p=1.0, cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_no_padding_batch(self, device, dtype):
         torch.manual_seed(42)
@@ -2095,7 +2250,7 @@ def test_no_padding_batch(self, device, dtype):
         )
         rc = RandomCrop(size=(2, 3), padding=None, align_corners=True, p=1.0)
         out = rc(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
 
         torch.manual_seed(42)
         inversed = torch.tensor(
@@ -2108,8 +2263,8 @@ def test_no_padding_batch(self, device, dtype):
         )
         aug = RandomCrop(size=(2, 3), padding=None, align_corners=True, p=1.0, cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_same_on_batch(self, device, dtype):
         f = RandomCrop(size=(2, 3), padding=1, same_on_batch=True, align_corners=True, p=1.0)
@@ -2127,16 +2282,16 @@ def test_padding(self, device, dtype):
         torch.manual_seed(42)
         out2 = rc(inp.squeeze())
 
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(out2, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(out2, expected)
         torch.manual_seed(42)
         inversed = torch.tensor([[[[0.0, 0.0, 0.0], [0.0, 0.0, 0.0], [0.0, 7.0, 8.0]]]], device=device, dtype=dtype)
         aug = RandomCrop(
             size=(2, 3), padding=1, padding_mode='reflect', align_corners=True, p=1.0, cropping_mode="resample"
         )
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out, padding_mode="constant"), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out, padding_mode="constant"), inversed)
 
     def test_padding_batch_1(self, device, dtype):
         torch.manual_seed(42)
@@ -2150,7 +2305,7 @@ def test_padding_batch_1(self, device, dtype):
         rc = RandomCrop(size=(2, 3), padding=1, align_corners=True, p=1.0)
         out = rc(inp)
 
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
 
         torch.manual_seed(42)
         inversed = torch.tensor(
@@ -2163,8 +2318,8 @@ def test_padding_batch_1(self, device, dtype):
         )
         aug = RandomCrop(size=(2, 3), padding=1, align_corners=True, p=1.0, cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_padding_batch_2(self, device, dtype):
         torch.manual_seed(42)
@@ -2178,7 +2333,7 @@ def test_padding_batch_2(self, device, dtype):
         rc = RandomCrop(size=(2, 3), padding=(0, 1), fill=10, align_corners=True, p=1.0)
         out = rc(inp)
 
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
         torch.manual_seed(42)
         inversed = torch.tensor(
             [
@@ -2190,8 +2345,8 @@ def test_padding_batch_2(self, device, dtype):
         )
         aug = RandomCrop(size=(2, 3), padding=(0, 1), fill=10, align_corners=True, p=1.0, cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_padding_batch_3(self, device, dtype):
         torch.manual_seed(0)
@@ -2205,7 +2360,7 @@ def test_padding_batch_3(self, device, dtype):
         rc = RandomCrop(size=(2, 3), padding=(0, 1, 2, 3), fill=8, align_corners=True, p=1.0)
         out = rc(inp)
 
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
 
         torch.manual_seed(0)
         inversed = torch.tensor(
@@ -2218,8 +2373,8 @@ def test_padding_batch_3(self, device, dtype):
         )
         aug = RandomCrop(size=(2, 3), padding=(0, 1, 2, 3), fill=8, align_corners=True, p=1.0, cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_padding_no_forward(self, device, dtype):
         torch.manual_seed(0)
@@ -2229,8 +2384,8 @@ def test_padding_no_forward(self, device, dtype):
         rc = RandomCrop(size=(2, 3), padding=(0, 1, 2, 3), fill=9, align_corners=True, p=0.0, cropping_mode="resample")
 
         out = rc(inp)
-        assert_close(out, inp, atol=1e-4, rtol=1e-4)
-        assert_close(rc.transform_matrix, trans, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, inp)
+        self.assert_close(rc.transform_matrix, trans)
 
     def test_pad_if_needed(self, device, dtype):
         torch.manual_seed(0)
@@ -2242,14 +2397,14 @@ def test_pad_if_needed(self, device, dtype):
         rc = RandomCrop(size=(2, 3), pad_if_needed=True, fill=9, align_corners=True, p=1.0)
         out = rc(inp)
 
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
 
         torch.manual_seed(0)
         inversed = torch.tensor([[[[0.0, 1.0, 2.0]]], [[[0.0, 1.0, 2.0]]]], device=device, dtype=dtype)
         aug = RandomCrop(size=(2, 3), pad_if_needed=True, fill=9, align_corners=True, p=1.0, cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_crop_modes(self, device, dtype):
         torch.manual_seed(0)
@@ -2260,7 +2415,7 @@ def test_crop_modes(self, device, dtype):
 
         op2 = RandomCrop(size=(2, 2), cropping_mode='slice')
 
-        assert_close(out, op2(img, op1._params))
+        self.assert_close(out, op2(img, op1._params))
 
     def test_gradcheck(self, device, dtype):
         torch.manual_seed(0)  # for random reproductibility
@@ -2277,7 +2432,7 @@ def test_jit(self, device, dtype):
 
         actual = op_script(img)
         expected = kornia.geometry.transform.center_crop3d(img)
-        assert_close(actual, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(actual, expected)
 
     @pytest.mark.skip("Need to fix Union type")
     def test_jit_trace(self, device, dtype):
@@ -2295,10 +2450,25 @@ def test_jit_trace(self, device, dtype):
         # 3. Evaluate
         actual = op_trace(img)
         expected = op(img)
-        assert_close(actual, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(actual, expected)
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
 
 
-class TestRandomResizedCrop:
+class TestRandomResizedCrop(BaseTester):
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
     @pytest.mark.xfail(reason="might fail under windows OS due to printing preicision.")
@@ -2319,13 +2489,13 @@ def test_no_resize(self, device, dtype):
         rrc = RandomResizedCrop(size=(2, 3), scale=(1.0, 1.0), ratio=(1.0, 1.0))
         # It will crop a size of (2, 3) from the aspect ratio implementation of torch
         out = rrc(inp)
-        assert_close(out, expected, rtol=1e-4, atol=1e-4)
+        self.assert_close(out, expected)
 
         torch.manual_seed(0)
         aug = RandomResizedCrop(size=(2, 3), scale=(1.0, 1.0), ratio=(1.0, 1.0), cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inp[None], atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inp[None])
 
     def test_same_on_batch(self, device, dtype):
         f = RandomResizedCrop(size=(2, 3), scale=(1.0, 1.0), ratio=(1.0, 1.0), same_on_batch=True)
@@ -2333,7 +2503,7 @@ def test_same_on_batch(self, device, dtype):
             2, 1, 1, 1
         )
         res = f(input)
-        assert_close(res[0], res[1])
+        self.assert_close(res[0], res[1])
 
         torch.manual_seed(0)
         aug = RandomResizedCrop(
@@ -2341,7 +2511,7 @@ def test_same_on_batch(self, device, dtype):
         )
         out = aug(input)
         inversed = aug.inverse(out)
-        assert_close(inversed[0], inversed[1])
+        self.assert_close(inversed[0], inversed[1])
 
     def test_crop_scale_ratio(self, device, dtype):
         # This is included in doctest
@@ -2356,14 +2526,14 @@ def test_crop_scale_ratio(self, device, dtype):
         rrc = RandomResizedCrop(size=(3, 3), scale=(3.0, 3.0), ratio=(2.0, 2.0))
         # It will crop a size of (3, 3) from the aspect ratio implementation of torch
         out = rrc(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
 
         torch.manual_seed(0)
         inversed = torch.tensor([[[[0.0, 1.0, 2.0], [0.0, 4.0, 5.0], [0.0, 7.0, 8.0]]]], device=device, dtype=dtype)
         aug = RandomResizedCrop(size=(3, 3), scale=(3.0, 3.0), ratio=(2.0, 2.0), cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_crop_size_greater_than_input(self, device, dtype):
         # This is included in doctest
@@ -2389,14 +2559,14 @@ def test_crop_size_greater_than_input(self, device, dtype):
         # It will crop a size of (3, 3) from the aspect ratio implementation of torch
         out = rrc(inp)
         assert out.shape == torch.Size([1, 1, 4, 4])
-        assert_close(out, exp, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, exp)
 
         torch.manual_seed(0)
         inversed = torch.tensor([[[[0.0, 1.0, 2.0], [0.0, 4.0, 5.0], [0.0, 7.0, 8.0]]]], device=device, dtype=dtype)
         aug = RandomResizedCrop(size=(4, 4), scale=(3.0, 3.0), ratio=(2.0, 2.0), cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, exp, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, exp)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_crop_scale_ratio_batch(self, device, dtype):
         torch.manual_seed(0)
@@ -2416,7 +2586,7 @@ def test_crop_scale_ratio_batch(self, device, dtype):
         rrc = RandomResizedCrop(size=(3, 3), scale=(3.0, 3.0), ratio=(2.0, 2.0))
         # It will crop a size of (2, 2) from the aspect ratio implementation of torch
         out = rrc(inp)
-        assert_close(out, expected, rtol=1e-4, atol=1e-4)
+        self.assert_close(out, expected)
 
         torch.manual_seed(0)
         inversed = torch.tensor(
@@ -2429,8 +2599,8 @@ def test_crop_scale_ratio_batch(self, device, dtype):
         )
         aug = RandomResizedCrop(size=(3, 3), scale=(3.0, 3.0), ratio=(2.0, 2.0), cropping_mode="resample")
         out = aug(inp)
-        assert_close(out, expected, atol=1e-4, rtol=1e-4)
-        assert_close(aug.inverse(out), inversed, atol=1e-4, rtol=1e-4)
+        self.assert_close(out, expected)
+        self.assert_close(aug.inverse(out), inversed)
 
     def test_crop_modes(self, device, dtype):
         torch.manual_seed(0)
@@ -2441,7 +2611,7 @@ def test_crop_modes(self, device, dtype):
 
         op2 = RandomResizedCrop(size=(4, 4), cropping_mode='slice')
 
-        assert_close(out, op2(img, op1._params))
+        self.assert_close(out, op2(img, op1._params))
 
     def test_gradcheck(self, device, dtype):
         torch.manual_seed(0)  # for random reproductibility
@@ -2451,8 +2621,28 @@ def test_gradcheck(self, device, dtype):
             RandomResizedCrop(size=(3, 3), scale=(1.0, 1.0), ratio=(1.0, 1.0)), (inp,), raise_exception=True
         )
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
 
-class TestRandomEqualize:
+class TestRandomEqualize(BaseTester):
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
     @pytest.mark.xfail(reason="might fail under windows OS due to printing precision.")
@@ -2496,10 +2686,10 @@ def test_random_equalize(self, device, dtype):
         expected = self.build_input(channels, height, width, bs=1, row=row_expected, device=device, dtype=dtype)
         identity = kornia.eye_like(3, expected)  # 3 x 3
 
-        assert_close(f(inputs), expected, rtol=1e-4, atol=1e-4)
-        assert_close(f.transform_matrix, identity, rtol=1e-4, atol=1e-4)
-        assert_close(f1(inputs), inputs, rtol=1e-4, atol=1e-4)
-        assert_close(f1.transform_matrix, identity, rtol=1e-4, atol=1e-4)
+        self.assert_close(f(inputs), expected)
+        self.assert_close(f.transform_matrix, identity)
+        self.assert_close(f1(inputs), inputs)
+        self.assert_close(f1.transform_matrix, identity)
 
     def test_batch_random_equalize(self, device, dtype):
         f = RandomEqualize(p=1.0)
@@ -2537,10 +2727,10 @@ def test_batch_random_equalize(self, device, dtype):
 
         identity = kornia.eye_like(3, expected)  # 2 x 3 x 3
 
-        assert_close(f(inputs), expected, rtol=1e-4, atol=1e-4)
-        assert_close(f.transform_matrix, identity, rtol=1e-4, atol=1e-4)
-        assert_close(f1(inputs), inputs, rtol=1e-4, atol=1e-4)
-        assert_close(f1.transform_matrix, identity, rtol=1e-4, atol=1e-4)
+        self.assert_close(f(inputs), expected)
+        self.assert_close(f.transform_matrix, identity)
+        self.assert_close(f1(inputs), inputs)
+        self.assert_close(f1.transform_matrix, identity)
 
     def test_same_on_batch(self, device, dtype):
         f = RandomEqualize(p=0.5, same_on_batch=True)
@@ -2568,6 +2758,26 @@ def build_input(channels, height, width, bs=1, row=None, device='cpu', dtype=tor
 
         return batch.to(device, dtype)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
 
 class TestGaussianBlur:
 
@@ -2580,13 +2790,38 @@ def test_smoke(self):
         assert str(f) == repr
 
 
-class TestRandomInvert:
+class TestRandomInvert(BaseTester):
     def test_smoke(self, device, dtype):
         img = torch.ones(1, 3, 4, 5, device=device, dtype=dtype)
-        assert_close(RandomInvert(p=1.0)(img), torch.zeros_like(img))
+        self.assert_close(RandomInvert(p=1.0)(img), torch.zeros_like(img))
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
 
-class TestRandomChannelShuffle:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_gradcheck(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+
+class TestRandomChannelShuffle(BaseTester):
     def test_smoke(self, device, dtype):
         torch.manual_seed(0)
         img = torch.arange(1 * 3 * 2 * 2, device=device, dtype=dtype).view(1, 3, 2, 2)
@@ -2599,7 +2834,32 @@ def test_smoke(self, device, dtype):
 
         aug = RandomChannelShuffle(p=1.0)
         out = aug(img)
-        assert_close(out, out_expected)
+        self.assert_close(out, out_expected)
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_gradcheck(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
 
 
 class TestRandomGaussianNoise:
@@ -2610,7 +2870,7 @@ def test_smoke(self, device, dtype):
         assert img.shape == aug(img).shape
 
 
-class TestNormalize:
+class TestNormalize(BaseTester):
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
     @pytest.mark.xfail(reason="might fail under windows OS due to printing preicision.")
@@ -2619,18 +2879,17 @@ def test_smoke(self, device, dtype):
         repr = "Normalize(mean=torch.tensor([1.]), std=torch.tensor([1.]), p=1., p_batch=1.0, " "same_on_batch=False)"
         assert str(f) == repr
 
-    @staticmethod
     @pytest.mark.parametrize(
         "mean, std", [((1.0, 1.0, 1.0), (0.5, 0.5, 0.5)), (1.0, 0.5), (torch.tensor([1.0]), torch.tensor([0.5]))]
     )
-    def test_random_normalize_different_parameter_types(mean, std):
+    def test_random_normalize_different_parameter_types(self, mean, std):
         f = Normalize(mean=mean, std=std, p=1)
         data = torch.ones(2, 3, 256, 313)
         if isinstance(mean, float):
             expected = (data - torch.as_tensor(mean)) / torch.as_tensor(std)
         else:
             expected = (data - torch.as_tensor(mean[0])) / torch.as_tensor(std[0])
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @staticmethod
     @pytest.mark.parametrize("mean, std", [((1.0, 1.0, 1.0, 1.0), (0.5, 0.5, 0.5, 0.5)), ((1.0, 1.0), (0.5, 0.5))])
@@ -2650,10 +2909,10 @@ def test_random_normalize(self, device, dtype):
 
         identity = kornia.eye_like(3, expected)
 
-        assert_close(f(inputs), expected, rtol=1e-4, atol=1e-4)
-        assert_close(f.transform_matrix, identity, rtol=1e-4, atol=1e-4)
-        assert_close(f1(inputs), inputs, rtol=1e-4, atol=1e-4)
-        assert_close(f1.transform_matrix, identity, rtol=1e-4, atol=1e-4)
+        self.assert_close(f(inputs), expected)
+        self.assert_close(f.transform_matrix, identity)
+        self.assert_close(f1(inputs), inputs)
+        self.assert_close(f1.transform_matrix, identity)
 
     def test_batch_random_normalize(self, device, dtype):
         f = Normalize(mean=torch.tensor([1.0]), std=torch.tensor([0.5]), p=1.0)
@@ -2665,10 +2924,10 @@ def test_batch_random_normalize(self, device, dtype):
 
         identity = kornia.eye_like(3, expected)
 
-        assert_close(f(inputs), expected, rtol=1e-4, atol=1e-4)
-        assert_close(f.transform_matrix, identity, rtol=1e-4, atol=1e-4)
-        assert_close(f1(inputs), inputs, rtol=1e-4, atol=1e-4)
-        assert_close(f1.transform_matrix, identity, rtol=1e-4, atol=1e-4)
+        self.assert_close(f(inputs), expected)
+        self.assert_close(f.transform_matrix, identity)
+        self.assert_close(f1(inputs), inputs)
+        self.assert_close(f1.transform_matrix, identity)
 
     def test_gradcheck(self, device, dtype):
 
@@ -2680,8 +2939,28 @@ def test_gradcheck(self, device, dtype):
             Normalize(mean=torch.tensor([1.0]), std=torch.tensor([1.0]), p=1.0), (input,), raise_exception=True
         )
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
 
-class TestDenormalize:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+
+class TestDenormalize(BaseTester):
     # TODO: improve and implement more meaningful smoke tests e.g check for a consistent
     # return values such a Tensor variable.
     @pytest.mark.xfail(reason="might fail under windows OS due to printing preicision.")
@@ -2700,10 +2979,10 @@ def test_random_denormalize(self, device, dtype):
 
         identity = kornia.eye_like(3, expected)
 
-        assert_close(f(inputs), expected, rtol=1e-4, atol=1e-4)
-        assert_close(f.transform_matrix, identity, rtol=1e-4, atol=1e-4)
-        assert_close(f1(inputs), inputs, rtol=1e-4, atol=1e-4)
-        assert_close(f1.transform_matrix, identity, rtol=1e-4, atol=1e-4)
+        self.assert_close(f(inputs), expected)
+        self.assert_close(f.transform_matrix, identity)
+        self.assert_close(f1(inputs), inputs)
+        self.assert_close(f1.transform_matrix, identity)
 
     def test_batch_random_denormalize(self, device, dtype):
         f = Denormalize(mean=torch.tensor([1.0]), std=torch.tensor([0.5]), p=1.0)
@@ -2715,10 +2994,10 @@ def test_batch_random_denormalize(self, device, dtype):
 
         identity = kornia.eye_like(3, expected)
 
-        assert_close(f(inputs), expected, rtol=1e-4, atol=1e-4)
-        assert_close(f.transform_matrix, identity, rtol=1e-4, atol=1e-4)
-        assert_close(f1(inputs), inputs, rtol=1e-4, atol=1e-4)
-        assert_close(f1.transform_matrix, identity, rtol=1e-4, atol=1e-4)
+        self.assert_close(f(inputs), expected)
+        self.assert_close(f.transform_matrix, identity)
+        self.assert_close(f1(inputs), inputs)
+        self.assert_close(f1.transform_matrix, identity)
 
     def test_gradcheck(self, device, dtype):
 
@@ -2730,6 +3009,26 @@ def test_gradcheck(self, device, dtype):
             Denormalize(mean=torch.tensor([1.0]), std=torch.tensor([1.0]), p=1.0), (input,), raise_exception=True
         )
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
 
 class TestRandomFisheye:
     def test_smoke(self, device, dtype):
@@ -2842,7 +3141,7 @@ def test_plasma_contrast(self, device, dtype):
         assert out.shape == (2, 3, 4, 5)
 
 
-class TestPlanckianJitter:
+class TestPlanckianJitter(BaseTester):
     def _get_expected_output_blackbody(self, device, dtype):
         return torch.tensor(
             [
@@ -3028,14 +3327,14 @@ def test_planckian_jitter_blackbody(self, device, dtype):
         f = RandomPlanckianJitter(select_from=1).to(device, dtype)
         input = self._get_input(device, dtype)
         expected = self._get_expected_output_blackbody(device, dtype)
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_planckian_jitter_cied(self, device, dtype):
         torch.manual_seed(0)
         f = RandomPlanckianJitter(mode='CIED', select_from=1).to(device, dtype)
         input = self._get_input(device, dtype)
         expected = self._get_expected_output_cied(device, dtype)
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_planckian_jitter_batch(self, device, dtype):
         torch.manual_seed(0)
@@ -3044,7 +3343,7 @@ def test_planckian_jitter_batch(self, device, dtype):
         select_from = [1, 2, 24]
         f = RandomPlanckianJitter(select_from=select_from).to(device, dtype)
         expected = self._get_expected_output_batch(device, dtype)
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
 
     def test_planckian_jitter_same_on_batch(self, device, dtype):
         torch.manual_seed(0)
@@ -3053,7 +3352,37 @@ def test_planckian_jitter_same_on_batch(self, device, dtype):
         select_from = [1, 2, 24, 3, 4, 5]
         f = RandomPlanckianJitter(select_from=select_from, same_on_batch=True, p=1.0).to(device, dtype)
         expected = self._get_expected_output_same_on_batch(device, dtype)
-        assert_close(f(input), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(input), expected)
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_gradcheck(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
 
 
 class TestRandomRGBShift:
diff --git a/test/color/test_hls.py b/test/color/test_hls.py
index ea8ce09011..2ccdd2fe10 100644
--- a/test/color/test_hls.py
+++ b/test/color/test_hls.py
@@ -6,7 +6,7 @@
 from torch.autograd import gradcheck
 
 import kornia
-from kornia.testing import BaseTester, assert_close
+from kornia.testing import BaseTester
 from packaging import version
 
 
@@ -91,7 +91,7 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        assert_close(kornia.color.rgb_to_hls(data), expected)
+        self.assert_close(kornia.color.rgb_to_hls(data), expected)
 
     def test_nan_rgb_to_hls(self, device, dtype):
         if device != torch.device('cpu') and version.parse(torch.__version__) < version.parse('1.7.0'):
@@ -114,7 +114,7 @@ def test_nan_rgb_to_hls(self, device, dtype):
             ],
             dim=1,
         )
-        assert_close(kornia.color.rgb_to_hls(data), expected)
+        self.assert_close(kornia.color.rgb_to_hls(data), expected)
 
     def test_nan_random_extreme_values(self, device, dtype):
         # generate extreme colors randomly
@@ -141,7 +141,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_hls
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -149,7 +149,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToHls().to(device, dtype)
         fcn = kornia.color.rgb_to_hls
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestHlsToRgb(BaseTester):
@@ -240,13 +240,13 @@ def test_unit(self, device, dtype):
         )
 
         f = kornia.color.hls_to_rgb
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
         data[:, 0] += 2 * math.pi
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
         data[:, 0] -= 4 * math.pi
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -268,7 +268,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.hls_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -276,4 +276,4 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.HlsToRgb().to(device, dtype)
         fcn = kornia.color.hls_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
diff --git a/test/color/test_hsv.py b/test/color/test_hsv.py
index a897c34dcf..04aafd05c9 100644
--- a/test/color/test_hsv.py
+++ b/test/color/test_hsv.py
@@ -5,7 +5,7 @@
 from torch.autograd import gradcheck
 
 import kornia
-from kornia.testing import BaseTester, assert_close
+from kornia.testing import BaseTester
 
 
 class TestRgbToHsv(BaseTester):
@@ -89,12 +89,12 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        assert_close(kornia.color.rgb_to_hsv(data), expected)
+        self.assert_close(kornia.color.rgb_to_hsv(data), expected)
 
     def test_nan_rgb_to_hsv(self, device, dtype):
         data = torch.zeros(3, 5, 5, device=device, dtype=dtype)  # 3x5x5
         expected = torch.zeros_like(data)  # 3x5x5
-        assert_close(kornia.color.rgb_to_hsv(data), expected)
+        self.assert_close(kornia.color.rgb_to_hsv(data), expected)
 
     def test_gradcheck(self, device, dtype):
         B, C, H, W = 2, 3, 4, 4
@@ -106,14 +106,14 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_hsv
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     def test_module(self, device, dtype):
         B, C, H, W = 2, 3, 4, 4
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToHsv().to(device, dtype)
         fcn = kornia.color.rgb_to_hsv
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestHsvToRgb(BaseTester):
@@ -202,13 +202,13 @@ def test_unit(self, device, dtype):
         )
 
         f = kornia.color.hsv_to_rgb
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
         data[:, 0] += 2 * math.pi
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
         data[:, 0] -= 4 * math.pi
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -222,7 +222,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.hsv_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -230,4 +230,4 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.HsvToRgb().to(device, dtype)
         fcn = kornia.color.hsv_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
diff --git a/test/color/test_lab.py b/test/color/test_lab.py
index 8dd368c637..8611ae388a 100644
--- a/test/color/test_lab.py
+++ b/test/color/test_lab.py
@@ -3,8 +3,7 @@
 from torch.autograd import gradcheck
 
 import kornia
-import kornia.testing as utils
-from kornia.testing import BaseTester, assert_close
+from kornia.testing import BaseTester
 
 
 class TestRgbToLab(BaseTester):
@@ -82,8 +81,7 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        tol_val: float = utils._get_precision_by_name(device, 'xla', 1e-1, 1e-4)
-        assert_close(kornia.color.rgb_to_lab(data), expected, rtol=tol_val, atol=tol_val)
+        self.assert_close(kornia.color.rgb_to_lab(data), expected)
 
     def test_forth_and_back(self, device, dtype):
         data = torch.rand(3, 4, 5, device=device, dtype=dtype)
@@ -91,8 +89,7 @@ def test_forth_and_back(self, device, dtype):
         rgb = kornia.color.lab_to_rgb
 
         data_out = lab(rgb(data, clip=False))
-        tol_val: float = utils._get_precision_by_name(device, 'xla', 1e-1, 1e-4)
-        assert_close(data_out, data, rtol=tol_val, atol=tol_val)
+        self.assert_close(data_out, data)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -106,7 +103,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_lab
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img), rtol=1e-3, atol=1e-3)
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -114,7 +111,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToLab().to(device, dtype)
         fcn = kornia.color.rgb_to_lab
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestLabToRgb(BaseTester):
@@ -223,9 +220,8 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        tol_val: float = utils._get_precision_by_name(device, 'xla', 1e-1, 1e-4)
-        assert_close(kornia.color.lab_to_rgb(data), expected, rtol=tol_val, atol=tol_val)
-        assert_close(kornia.color.lab_to_rgb(data, clip=False), expected_unclipped, rtol=tol_val, atol=tol_val)
+        self.assert_close(kornia.color.lab_to_rgb(data), expected)
+        self.assert_close(kornia.color.lab_to_rgb(data, clip=False), expected_unclipped)
 
     def test_forth_and_back(self, device, dtype):
         data = torch.rand(3, 4, 5, device=device, dtype=dtype)
@@ -233,8 +229,7 @@ def test_forth_and_back(self, device, dtype):
         rgb = kornia.color.lab_to_rgb
 
         unclipped_data_out = rgb(lab(data), clip=False)
-        tol_val: float = utils._get_precision_by_name(device, 'xla', 1e-1, 1e-4)
-        assert_close(unclipped_data_out, data, rtol=tol_val, atol=tol_val)
+        self.assert_close(unclipped_data_out, data)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -249,7 +244,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.lab_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -257,4 +252,4 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.LabToRgb().to(device, dtype)
         fcn = kornia.color.lab_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
diff --git a/test/color/test_luv.py b/test/color/test_luv.py
index 607622b38a..a1f7421c57 100644
--- a/test/color/test_luv.py
+++ b/test/color/test_luv.py
@@ -3,7 +3,7 @@
 from torch.autograd import gradcheck
 
 import kornia
-from kornia.testing import BaseTester, _get_precision, assert_close
+from kornia.testing import BaseTester
 
 
 class TestRgbToLuv(BaseTester):
@@ -81,8 +81,7 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        tol_val: float = _get_precision(device, dtype)
-        assert_close(kornia.color.rgb_to_luv(data), expected, rtol=tol_val, atol=tol_val)
+        self.assert_close(kornia.color.rgb_to_luv(data), expected)
 
     def test_forth_and_back(self, device, dtype):
         data = torch.rand(3, 4, 5, device=device, dtype=dtype)
@@ -90,7 +89,7 @@ def test_forth_and_back(self, device, dtype):
         rgb = kornia.color.luv_to_rgb
 
         data_out = luv(rgb(data))
-        assert_close(data_out, data, rtol=1e-4, atol=1e-4)
+        self.assert_close(data_out, data)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -104,7 +103,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_luv
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img), rtol=1e-3, atol=1e-3)
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -112,7 +111,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToLuv().to(device, dtype)
         fcn = kornia.color.rgb_to_luv
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestLuvToRgb(BaseTester):
@@ -195,7 +194,7 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        assert_close(kornia.color.luv_to_rgb(data), expected, rtol=1e-4, atol=1e-4)
+        self.assert_close(kornia.color.luv_to_rgb(data), expected)
 
     def test_forth_and_back(self, device, dtype):
         data = torch.rand(3, 4, 5, device=device, dtype=dtype)
@@ -203,7 +202,7 @@ def test_forth_and_back(self, device, dtype):
         rgb = kornia.color.luv_to_rgb
 
         data_out = rgb(luv(data))
-        assert_close(data_out, data, rtol=1e-4, atol=1e-4)
+        self.assert_close(data_out, data)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -218,7 +217,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.luv_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -226,4 +225,4 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.LuvToRgb().to(device, dtype)
         fcn = kornia.color.luv_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
diff --git a/test/color/test_rgb.py b/test/color/test_rgb.py
index adfff93fb6..39e0f489f1 100644
--- a/test/color/test_rgb.py
+++ b/test/color/test_rgb.py
@@ -3,7 +3,7 @@
 from torch.autograd import gradcheck
 
 import kornia
-from kornia.testing import BaseTester, assert_close
+from kornia.testing import BaseTester
 
 
 class TestRgbToBgr(BaseTester):
@@ -44,7 +44,7 @@ def test_back_and_forth(self, device, dtype):
         data_bgr = torch.rand(1, 3, 3, 2, device=device, dtype=dtype)
         data_rgb = kornia.color.bgr_to_rgb(data_bgr)
         data_bgr_new = kornia.color.rgb_to_bgr(data_rgb)
-        assert_close(data_bgr, data_bgr_new)
+        self.assert_close(data_bgr, data_bgr_new)
 
     def test_unit(self, device, dtype):
         data = torch.tensor(
@@ -56,7 +56,7 @@ def test_unit(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.color.rgb_to_bgr
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -70,7 +70,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_bgr
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -78,7 +78,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToBgr().to(device, dtype)
         fcn = kornia.color.rgb_to_bgr
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
     @pytest.mark.nn
     def test_module_bgr(self, device, dtype):
@@ -86,7 +86,7 @@ def test_module_bgr(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.BgrToRgb().to(device, dtype)
         fcn = kornia.color.bgr_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestRgbToRgba(BaseTester):
@@ -140,14 +140,14 @@ def test_back_and_forth_rgb(self, device, dtype):
         x_rgb = torch.ones(3, 4, 4, device=device, dtype=dtype)
         x_rgba = kornia.color.rgb_to_rgba(x_rgb, a_val)
         x_rgb_new = kornia.color.rgba_to_rgb(x_rgba)
-        assert_close(x_rgb, x_rgb_new)
+        self.assert_close(x_rgb, x_rgb_new)
 
     def test_back_and_forth_bgr(self, device, dtype):
         a_val: float = 1.0
         x_bgr = torch.ones(3, 4, 4, device=device, dtype=dtype)
         x_rgba = kornia.color.bgr_to_rgba(x_bgr, a_val)
         x_bgr_new = kornia.color.rgba_to_bgr(x_rgba)
-        assert_close(x_bgr, x_bgr_new)
+        self.assert_close(x_bgr, x_bgr_new)
 
     @pytest.mark.parametrize("aval", [0.4, 45.0])
     def test_unit(self, device, dtype, aval):
@@ -168,7 +168,7 @@ def test_unit(self, device, dtype, aval):
             dtype=dtype,
         )  # Bx4x2x2
 
-        assert_close(kornia.color.rgb_to_rgba(data, aval), expected)
+        self.assert_close(kornia.color.rgb_to_rgba(data, aval), expected)
 
     @pytest.mark.parametrize("aval", [0.4, 45.0])
     def test_unit_aval_th(self, device, dtype, aval):
@@ -190,7 +190,7 @@ def test_unit_aval_th(self, device, dtype, aval):
         )  # Bx4x2x2
 
         aval = torch.full_like(data[:, :1], aval)  # Bx1xHxW
-        assert_close(kornia.color.rgb_to_rgba(data, aval), expected)
+        self.assert_close(kornia.color.rgb_to_rgba(data, aval), expected)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -212,9 +212,9 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_rgba
         op_jit = torch.jit.script(op)
-        assert_close(op(img, 1.0), op_jit(img, 1.0))
+        self.assert_close(op(img, 1.0), op_jit(img, 1.0))
         aval = torch.ones(B, 1, H, W, device=device, dtype=dtype)
-        assert_close(op(img, aval), op_jit(img, aval))
+        self.assert_close(op(img, aval), op_jit(img, aval))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -222,7 +222,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToRgba(1.0).to(device, dtype)
         fcn = kornia.color.rgb_to_rgba
-        assert_close(ops(img), fcn(img, 1.0))
+        self.assert_close(ops(img), fcn(img, 1.0))
 
     @pytest.mark.nn
     def test_module_bgr(self, device, dtype):
@@ -230,7 +230,7 @@ def test_module_bgr(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.BgrToRgba(1.0).to(device, dtype)
         fcn = kornia.color.bgr_to_rgba
-        assert_close(ops(img), fcn(img, 1.0))
+        self.assert_close(ops(img), fcn(img, 1.0))
 
     @pytest.mark.nn
     def test_module_bgra2rgb(self, device, dtype):
@@ -238,7 +238,7 @@ def test_module_bgra2rgb(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbaToRgb().to(device, dtype)
         fcn = kornia.color.rgba_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
     @pytest.mark.nn
     def test_module_bgra2bgr(self, device, dtype):
@@ -246,7 +246,7 @@ def test_module_bgra2bgr(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbaToBgr().to(device, dtype)
         fcn = kornia.color.rgba_to_bgr
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestLinearRgb(BaseTester):
@@ -289,7 +289,7 @@ def test_back_and_forth(self, device, dtype):
         data_bgr = torch.rand(1, 3, 3, 2, device=device, dtype=dtype)
         data_rgb = kornia.color.rgb_to_linear_rgb(data_bgr)
         data_bgr_new = kornia.color.linear_rgb_to_rgb(data_rgb)
-        assert_close(data_bgr, data_bgr_new)
+        self.assert_close(data_bgr, data_bgr_new)
 
     def test_unit(self, device, dtype):
         data = torch.tensor(
@@ -307,7 +307,7 @@ def test_unit(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.color.rgb_to_linear_rgb
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_unit_linear(self, device, dtype):
         data = torch.tensor(
@@ -325,7 +325,7 @@ def test_unit_linear(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.color.linear_rgb_to_rgb
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -340,7 +340,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_linear_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.jit
     def test_jit_linear(self, device, dtype):
@@ -348,7 +348,7 @@ def test_jit_linear(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.linear_rgb_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -356,7 +356,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToLinearRgb().to(device, dtype)
         fcn = kornia.color.rgb_to_linear_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
     @pytest.mark.nn
     def test_module_linear(self, device, dtype):
@@ -364,4 +364,4 @@ def test_module_linear(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.LinearRgbToRgb().to(device, dtype)
         fcn = kornia.color.linear_rgb_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
diff --git a/test/color/test_xyz.py b/test/color/test_xyz.py
index fdd27b9de0..e76ddee389 100644
--- a/test/color/test_xyz.py
+++ b/test/color/test_xyz.py
@@ -3,7 +3,7 @@
 from torch.autograd import gradcheck
 
 import kornia
-from kornia.testing import BaseTester, assert_close
+from kornia.testing import BaseTester
 
 
 class TestRgbToXyz(BaseTester):
@@ -85,7 +85,7 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        assert_close(kornia.color.rgb_to_xyz(data), expected)
+        self.assert_close(kornia.color.rgb_to_xyz(data), expected)
 
     def test_forth_and_back(self, device, dtype):
         data = torch.rand(3, 4, 5, device=device, dtype=dtype)
@@ -93,7 +93,7 @@ def test_forth_and_back(self, device, dtype):
         rgb = kornia.color.xyz_to_rgb
 
         data_out = xyz(rgb(data))
-        assert_close(data_out, data)
+        self.assert_close(data_out, data)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -107,7 +107,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_xyz
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -115,7 +115,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToXyz().to(device, dtype)
         fcn = kornia.color.rgb_to_xyz
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestXyzToRgb(BaseTester):
@@ -197,7 +197,7 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        assert_close(kornia.color.xyz_to_rgb(data), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(kornia.color.xyz_to_rgb(data), expected)
 
     def test_forth_and_back(self, device, dtype):
         data = torch.rand(3, 4, 5, device=device, dtype=dtype)
@@ -205,7 +205,7 @@ def test_forth_and_back(self, device, dtype):
         rgb = kornia.color.xyz_to_rgb
 
         data_out = rgb(xyz(data))
-        assert_close(data_out, data)
+        self.assert_close(data_out, data)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -219,7 +219,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.xyz_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -227,4 +227,4 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.XyzToRgb().to(device, dtype)
         fcn = kornia.color.xyz_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
diff --git a/test/color/test_ycbcr.py b/test/color/test_ycbcr.py
index f0871a9913..dbab34a79a 100644
--- a/test/color/test_ycbcr.py
+++ b/test/color/test_ycbcr.py
@@ -3,7 +3,7 @@
 from torch.autograd import gradcheck
 
 import kornia
-from kornia.testing import BaseTester, assert_close
+from kornia.testing import BaseTester
 
 
 class TestRgbToYcbcr(BaseTester):
@@ -98,7 +98,7 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        assert_close(kornia.color.rgb_to_ycbcr(data), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(kornia.color.rgb_to_ycbcr(data), expected)
 
     # TODO: investigate and implement me
     # def test_forth_and_back(self, device, dtype):
@@ -116,7 +116,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_ycbcr
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -124,7 +124,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToYcbcr().to(device, dtype)
         fcn = kornia.color.rgb_to_ycbcr
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestYcbcrToRgb(BaseTester):
@@ -212,7 +212,7 @@ def test_unit(self, device, dtype):
             dtype=dtype,
         )
 
-        assert_close(kornia.color.ycbcr_to_rgb(data), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(kornia.color.ycbcr_to_rgb(data), expected)
 
     # TODO: investigate and implement me
     # def test_forth_and_back(self, device, dtype):
@@ -230,7 +230,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.ycbcr_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -238,4 +238,4 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.YcbcrToRgb().to(device, dtype)
         fcn = kornia.color.ycbcr_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
diff --git a/test/color/test_yuv.py b/test/color/test_yuv.py
index 907ae201a0..7bd223ffa2 100644
--- a/test/color/test_yuv.py
+++ b/test/color/test_yuv.py
@@ -3,7 +3,7 @@
 from torch.autograd import gradcheck
 
 import kornia
-from kornia.testing import BaseTester, assert_close
+from kornia.testing import BaseTester
 
 
 class TestRgbToYuv(BaseTester):
@@ -41,7 +41,7 @@ def test_forth_and_back(self, device, dtype):
         rgb = kornia.color.yuv_to_rgb
 
         data_out = rgb(yuv(data))
-        assert_close(data_out, data, rtol=1e-2, atol=1e-2)
+        self.assert_close(data_out, data, low_tolerance=True)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -55,7 +55,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_yuv
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -63,7 +63,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToYuv().to(device, dtype)
         fcn = kornia.color.rgb_to_yuv
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestRgbToYuv420(BaseTester):
@@ -123,8 +123,8 @@ def test_unit_white(self, device, dtype):  # skipcq: PYL-R0201
 
         resy = (kornia.color.rgb_to_yuv420(rgb)[0] * 255.0).round().type(torch.uint8)
         resuv = (kornia.color.rgb_to_yuv420(rgb)[1] * 255.0).round().clamp(-128, 127).type(torch.int8)
-        assert_close(refy, resy)
-        assert_close(refuv, resuv)
+        self.assert_close(refy, resy)
+        self.assert_close(refuv, resuv)
 
     def test_unit_black(self, device, dtype):  # skipcq: PYL-R0201
         rgb = (
@@ -138,8 +138,8 @@ def test_unit_black(self, device, dtype):  # skipcq: PYL-R0201
 
         resy = (kornia.color.rgb_to_yuv420(rgb)[0] * 255.0).round().type(torch.uint8)
         resuv = (kornia.color.rgb_to_yuv420(rgb)[1] * 255.0).round().clamp(-128, 127).type(torch.int8)
-        assert_close(refy, resy)
-        assert_close(refuv, resuv)
+        self.assert_close(refy, resy)
+        self.assert_close(refuv, resuv)
 
     def test_unit_gray(self, device, dtype):  # skipcq: PYL-R0201
         rgb = (
@@ -155,8 +155,8 @@ def test_unit_gray(self, device, dtype):  # skipcq: PYL-R0201
 
         resy = (kornia.color.rgb_to_yuv420(rgb)[0] * 255.0).round().type(torch.uint8)
         resuv = (kornia.color.rgb_to_yuv420(rgb)[1] * 255.0).round().clamp(-128, 127).type(torch.int8)
-        assert_close(refy, resy)
-        assert_close(refuv, resuv)
+        self.assert_close(refy, resy)
+        self.assert_close(refuv, resuv)
 
     def test_unit_red(self, device, dtype):  # skipcq: PYL-R0201
         rgb = (
@@ -170,8 +170,8 @@ def test_unit_red(self, device, dtype):  # skipcq: PYL-R0201
 
         resy = (kornia.color.rgb_to_yuv420(rgb)[0] * 255.0).round().type(torch.uint8)
         resuv = (kornia.color.rgb_to_yuv420(rgb)[1] * 255.0).round().clamp(-128, 127).type(torch.int8)
-        assert_close(refy, resy)
-        assert_close(refuv, resuv)
+        self.assert_close(refy, resy)
+        self.assert_close(refuv, resuv)
 
     def test_unit_blue(self, device, dtype):  # skipcq: PYL-R0201
         rgb = (
@@ -185,8 +185,8 @@ def test_unit_blue(self, device, dtype):  # skipcq: PYL-R0201
 
         resy = (kornia.color.rgb_to_yuv420(rgb)[0] * 255.0).type(torch.uint8)
         resuv = (kornia.color.rgb_to_yuv420(rgb)[1] * 255.0).clamp(-128, 127).type(torch.int8)
-        assert_close(refy, resy)
-        assert_close(refuv, resuv)
+        self.assert_close(refy, resy)
+        self.assert_close(refuv, resuv)
 
     # This measures accuracy, given the impact of the subsampling we will avoid the issue by
     # repeating a 2x2 pattern for which mean will match what we get from upscaling again
@@ -197,7 +197,7 @@ def test_forth_and_back(self, device, dtype):  # skipcq: PYL-R0201
         rgb = kornia.color.yuv420_to_rgb
         (a, b) = yuv(data)
         data_out = rgb(a, b)
-        assert_close(data_out, data, rtol=1e-2, atol=1e-2)
+        self.assert_close(data_out, data, low_tolerance=True)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -211,8 +211,8 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_yuv420
         op_jit = torch.jit.script(op)
-        assert_close(op(img)[0], op_jit(img)[0])
-        assert_close(op(img)[1], op_jit(img)[1])
+        self.assert_close(op(img)[0], op_jit(img)[0])
+        self.assert_close(op(img)[1], op_jit(img)[1])
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -220,8 +220,8 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToYuv420().to(device, dtype)
         fcn = kornia.color.rgb_to_yuv420
-        assert_close(ops(img)[0], fcn(img)[0])
-        assert_close(ops(img)[1], fcn(img)[1])
+        self.assert_close(ops(img)[0], fcn(img)[0])
+        self.assert_close(ops(img)[1], fcn(img)[1])
 
 
 class TestRgbToYuv422(BaseTester):
@@ -268,7 +268,7 @@ def test_forth_and_back(self, device, dtype):  # skipcq: PYL-R0201
         rgb = kornia.color.yuv422_to_rgb
         (a, b) = yuv(data)
         data_out = rgb(a, b)
-        assert_close(data_out, data, rtol=1e-2, atol=1e-2)
+        self.assert_close(data_out, data, low_tolerance=True)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -282,8 +282,8 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.rgb_to_yuv422
         op_jit = torch.jit.script(op)
-        assert_close(op(img)[0], op_jit(img)[0])
-        assert_close(op(img)[1], op_jit(img)[1])
+        self.assert_close(op(img)[0], op_jit(img)[0])
+        self.assert_close(op(img)[1], op_jit(img)[1])
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -291,8 +291,8 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.RgbToYuv422().to(device, dtype)
         fcn = kornia.color.rgb_to_yuv422
-        assert_close(ops(img)[0], fcn(img)[0])
-        assert_close(ops(img)[1], fcn(img)[1])
+        self.assert_close(ops(img)[0], fcn(img)[0])
+        self.assert_close(ops(img)[1], fcn(img)[1])
 
 
 class TestYuvToRgb(BaseTester):
@@ -329,7 +329,7 @@ def test_forth_and_back(self, device, dtype):  # skipcq: PYL-R0201
         yuv = kornia.color.rgb_to_yuv
 
         data_out = rgb(yuv(data))
-        assert_close(data_out, data, rtol=1e-2, atol=1e-2)
+        self.assert_close(data_out, data, low_tolerance=True)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -343,7 +343,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.color.yuv_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -351,7 +351,7 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         ops = kornia.color.YuvToRgb().to(device, dtype)
         fcn = kornia.color.yuv_to_rgb
-        assert_close(ops(img), fcn(img))
+        self.assert_close(ops(img), fcn(img))
 
 
 class TestYuv420ToRgb(BaseTester):
@@ -412,7 +412,7 @@ def test_unit_white(self, device, dtype):  # skipcq: PYL-R0201
         uv = torch.tensor([[[0]], [[0]]], device=device, dtype=torch.int8).type(torch.float) / 255.0
 
         resrgb = (kornia.color.yuv420_to_rgb(y, uv) * 255.0).round().type(torch.uint8)
-        assert_close(refrgb, resrgb)
+        self.assert_close(refrgb, resrgb)
 
     def test_unit_red(self, device, dtype):  # skipcq: PYL-R0201
         refrgb = torch.tensor(
@@ -422,7 +422,7 @@ def test_unit_red(self, device, dtype):  # skipcq: PYL-R0201
         uv = torch.tensor([[[-37]], [[127]]], device=device, dtype=torch.int8).type(torch.float) / 255.0
 
         resrgb = (kornia.color.yuv420_to_rgb(y, uv) * 255.0).round().type(torch.uint8)
-        assert_close(refrgb, resrgb)
+        self.assert_close(refrgb, resrgb)
 
     # TODO: improve accuracy
     def test_forth_and_back(self, device, dtype):  # skipcq: PYL-R0201
@@ -432,8 +432,8 @@ def test_forth_and_back(self, device, dtype):  # skipcq: PYL-R0201
         yuv = kornia.color.rgb_to_yuv420
 
         (data_outy, data_outuv) = yuv(rgb(datay, datauv))
-        assert_close(data_outy, datay, rtol=1e-2, atol=1e-2)
-        assert_close(data_outuv, datauv, rtol=1e-2, atol=1e-2)
+        self.assert_close(data_outy, datay, low_tolerance=True)
+        self.assert_close(data_outuv, datauv, low_tolerance=True)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -449,7 +449,7 @@ def test_jit(self, device, dtype):
         imguv = torch.ones(B, 2, int(H / 2), int(W / 2), device=device, dtype=dtype)
         op = kornia.color.yuv420_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(imgy, imguv), op_jit(imgy, imguv))
+        self.assert_close(op(imgy, imguv), op_jit(imgy, imguv))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -458,7 +458,7 @@ def test_module(self, device, dtype):
         imguv = torch.ones(B, 2, int(H / 2), int(W / 2), device=device, dtype=dtype)
         ops = kornia.color.Yuv420ToRgb().to(device, dtype)
         fcn = kornia.color.yuv420_to_rgb
-        assert_close(ops(imgy, imguv), fcn(imgy, imguv))
+        self.assert_close(ops(imgy, imguv), fcn(imgy, imguv))
 
 
 class TestYuv422ToRgb(BaseTester):
@@ -512,8 +512,8 @@ def test_forth_and_back(self, device, dtype):  # skipcq: PYL-R0201
         yuv = kornia.color.rgb_to_yuv422
 
         (data_outy, data_outuv) = yuv(rgb(datay, datauv))
-        assert_close(data_outy, datay, rtol=1e-2, atol=1e-2)
-        assert_close(data_outuv, datauv, rtol=1e-2, atol=1e-2)
+        self.assert_close(data_outy, datay, low_tolerance=True)
+        self.assert_close(data_outuv, datauv, low_tolerance=True)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -529,7 +529,7 @@ def test_jit(self, device, dtype):
         imguv = torch.ones(B, 2, H, int(W / 2), device=device, dtype=dtype)
         op = kornia.color.yuv422_to_rgb
         op_jit = torch.jit.script(op)
-        assert_close(op(imgy, imguv), op_jit(imgy, imguv))
+        self.assert_close(op(imgy, imguv), op_jit(imgy, imguv))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -538,4 +538,4 @@ def test_module(self, device, dtype):
         imguv = torch.ones(B, 2, H, int(W / 2), device=device, dtype=dtype)
         ops = kornia.color.Yuv422ToRgb().to(device, dtype)
         fcn = kornia.color.yuv422_to_rgb
-        assert_close(ops(imgy, imguv), fcn(imgy, imguv))
+        self.assert_close(ops(imgy, imguv), fcn(imgy, imguv))
diff --git a/test/enhance/test_adjust.py b/test/enhance/test_adjust.py
index 34de7f87f2..b6d2d837a9 100644
--- a/test/enhance/test_adjust.py
+++ b/test/enhance/test_adjust.py
@@ -4,12 +4,11 @@
 from torch.autograd import gradcheck
 
 import kornia
-import kornia.testing as utils
 from kornia.constants import pi
-from kornia.testing import BaseTester, assert_close, tensor_to_gradcheck_var
+from kornia.testing import BaseTester, tensor_to_gradcheck_var
 
 
-class TestInvert:
+class TestInvert(BaseTester):
     def test_smoke(self, device, dtype):
         img = torch.rand(1, 3, 4, 4, device=device, dtype=dtype)
         assert kornia.enhance.invert(img) is not None
@@ -23,12 +22,12 @@ def test_cardinality(self, device, dtype, shape):
     def test_max_val_1(self, device, dtype):
         img = torch.ones(1, 3, 4, 4, device=device, dtype=dtype)
         out = kornia.enhance.invert(img, torch.tensor(1.0))
-        assert_close(out, torch.zeros_like(out))
+        self.assert_close(out, torch.zeros_like(out))
 
     def test_max_val_255(self, device, dtype):
         img = 255.0 * torch.ones(1, 3, 4, 4, device=device, dtype=dtype)
         out = kornia.enhance.invert(img, torch.tensor(255.0))
-        assert_close(out, torch.zeros_like(out))
+        self.assert_close(out, torch.zeros_like(out))
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -43,7 +42,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.enhance.invert
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.nn
     def test_module(self, device, dtype):
@@ -51,10 +50,15 @@ def test_module(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.enhance.invert
         op_mod = kornia.enhance.Invert()
-        assert_close(op(img), op_mod(img))
+        self.assert_close(op(img), op_mod(img))
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
 
-class TestAdjustSaturation:
+
+class TestAdjustSaturation(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 4, 4), (2, 3, 3, 3), (4, 3, 3, 1, 1)])
     def test_cardinality(self, device, dtype, shape):
         img = torch.rand(shape, device=device, dtype=dtype)
@@ -77,7 +81,7 @@ def test_saturation_one(self, device, dtype):
         expected = data.clone()
 
         f = kornia.enhance.AdjustSaturation(1.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_saturation_with_gray_subtraction_one(self, device, dtype):
         data = torch.tensor(
@@ -89,7 +93,7 @@ def test_saturation_with_gray_subtraction_one(self, device, dtype):
         expected = data.clone()
 
         f = kornia.enhance.AdjustSaturationWithGraySubtraction(1.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_saturation_one_batch(self, device, dtype):
         data = torch.tensor(
@@ -103,7 +107,7 @@ def test_saturation_one_batch(self, device, dtype):
 
         expected = data
         f = kornia.enhance.AdjustSaturation(torch.ones(2))
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_saturation_with_gray_subtraction_one_batch(self, device, dtype):
         data = torch.tensor(
@@ -117,7 +121,7 @@ def test_saturation_with_gray_subtraction_one_batch(self, device, dtype):
 
         expected = data
         f = kornia.enhance.AdjustSaturationWithGraySubtraction(torch.ones(2))
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_gradcheck(self, device, dtype):
         batch_size, channels, height, width = 2, 3, 4, 5
@@ -131,8 +135,28 @@ def test_gradcheck_with_gray_subtraction(self, device, dtype):
         img = tensor_to_gradcheck_var(img)  # to var
         assert gradcheck(kornia.enhance.adjust_saturation_with_gray_subtraction, (img, 2.0), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
 
-class TestAdjustHue:
+class TestAdjustHue(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 4, 4), (2, 3, 3, 3), (4, 3, 3, 1, 1)])
     def test_cardinality(self, device, dtype, shape):
         img = torch.rand(shape, device=device, dtype=dtype)
@@ -149,7 +173,7 @@ def test_hue_one(self, device, dtype):
         expected = data.clone()
 
         f = kornia.enhance.AdjustHue(0.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_hue_one_batch(self, device, dtype):
         data = torch.tensor(
@@ -163,7 +187,7 @@ def test_hue_one_batch(self, device, dtype):
 
         expected = data
         f = kornia.enhance.AdjustHue(torch.tensor([0, 0]))
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_hue_flip_batch(self, device, dtype):
         data = torch.tensor(
@@ -179,7 +203,7 @@ def test_hue_flip_batch(self, device, dtype):
         f = kornia.enhance.AdjustHue(pi_t)
 
         result = f(data)
-        assert_close(result, result.flip(0))
+        self.assert_close(result, result.flip(0))
 
     def test_gradcheck(self, device, dtype):
         batch_size, channels, height, width = 2, 3, 4, 5
@@ -187,8 +211,28 @@ def test_gradcheck(self, device, dtype):
         img = tensor_to_gradcheck_var(img)  # to var
         assert gradcheck(kornia.enhance.adjust_hue, (img, 2.0), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
 
-class TestAdjustGamma:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
+
+class TestAdjustGamma(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 4, 4), (2, 3, 3, 3), (4, 3, 3, 1, 1)])
     def test_cardinality(self, device, dtype, shape):
         img = torch.rand(shape, device=device, dtype=dtype)
@@ -205,7 +249,7 @@ def test_gamma_zero(self, device, dtype):
         expected = torch.ones_like(data)
 
         f = kornia.enhance.AdjustGamma(0.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_gamma_one(self, device, dtype):
         data = torch.tensor(
@@ -217,7 +261,7 @@ def test_gamma_one(self, device, dtype):
         expected = data.clone()
 
         f = kornia.enhance.AdjustGamma(1.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_gamma_one_gain_two(self, device, dtype):
         data = torch.tensor(
@@ -231,7 +275,7 @@ def test_gamma_one_gain_two(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.enhance.AdjustGamma(1.0, 2.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_gamma_two(self, device, dtype):
         data = torch.tensor(
@@ -247,7 +291,7 @@ def test_gamma_two(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.enhance.AdjustGamma(2.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_gamma_two_batch(self, device, dtype):
         data = torch.tensor(
@@ -272,7 +316,7 @@ def test_gamma_two_batch(self, device, dtype):
         p2 = torch.ones(2, device=device, dtype=dtype)
 
         f = kornia.enhance.AdjustGamma(p1, gain=p2)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_gradcheck(self, device, dtype):
         batch_size, channels, height, width = 2, 3, 4, 5
@@ -280,8 +324,28 @@ def test_gradcheck(self, device, dtype):
         img = tensor_to_gradcheck_var(img)  # to var
         assert gradcheck(kornia.enhance.adjust_gamma, (img, 1.0, 2.0), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
 
-class TestAdjustContrast:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
+
+class TestAdjustContrast(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 4, 4), (2, 3, 3, 3), (4, 3, 3, 1, 1)])
     def test_cardinality(self, device, dtype, shape):
         img = torch.rand(shape, device=device, dtype=dtype)
@@ -305,7 +369,7 @@ def test_factor_zero(self, device, dtype):
         expected = torch.zeros_like(data)
 
         f = kornia.enhance.AdjustContrast(0.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_zero_with_mean_subtraction(self, device, dtype):
         # prepare input data
@@ -326,7 +390,7 @@ def test_factor_zero_with_mean_subtraction(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.enhance.AdjustContrastWithMeanSubtraction(0.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_one_acumulative(self, device, dtype):
         # prepare input data
@@ -339,7 +403,7 @@ def test_factor_one_acumulative(self, device, dtype):
         expected = data.clone()
 
         f = kornia.enhance.AdjustContrast(1.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_one_with_mean_subtraction(self, device, dtype):
         # prepare input data
@@ -352,7 +416,7 @@ def test_factor_one_with_mean_subtraction(self, device, dtype):
         expected = data.clone()
 
         f = kornia.enhance.AdjustContrastWithMeanSubtraction(1.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_two(self, device, dtype):
         # prepare input data
@@ -367,7 +431,7 @@ def test_factor_two(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.enhance.AdjustContrast(2.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_two_with_mean_subtraction(self, device, dtype):
         # prepare input data
@@ -388,7 +452,7 @@ def test_factor_two_with_mean_subtraction(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.enhance.AdjustContrastWithMeanSubtraction(2.0)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_tensor(self, device, dtype):
         # prepare input data
@@ -417,7 +481,7 @@ def test_factor_tensor(self, device, dtype):
         factor = torch.tensor([0, 1, 1.5, 2], device=device, dtype=dtype)
 
         f = kornia.enhance.AdjustContrast(factor)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_tensor_color(self, device, dtype):
         # prepare input data
@@ -442,7 +506,7 @@ def test_factor_tensor_color(self, device, dtype):
         factor = torch.tensor([1, 2], device=device, dtype=dtype)
 
         f = kornia.enhance.AdjustContrast(factor)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_tensor_color_with_mean_subtraction(self, device, dtype):
         # prepare input data
@@ -467,7 +531,7 @@ def test_factor_tensor_color_with_mean_subtraction(self, device, dtype):
         factor = torch.tensor([1, 2], device=device, dtype=dtype)
 
         f = kornia.enhance.AdjustContrastWithMeanSubtraction(factor)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_tensor_shape(self, device, dtype):
         # prepare input data
@@ -508,7 +572,7 @@ def test_factor_tensor_shape(self, device, dtype):
         factor = torch.tensor([1.5, 2.0], device=device, dtype=dtype)
 
         f = kornia.enhance.AdjustContrast(factor)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_factor_tensor_shape_with_mean_subtraction(self, device, dtype):
         # prepare input data
@@ -550,7 +614,7 @@ def test_factor_tensor_shape_with_mean_subtraction(self, device, dtype):
 
         f = kornia.enhance.AdjustContrastWithMeanSubtraction(factor)
 
-        assert_close(f(data), expected, rtol=1e-4, atol=1e-4)
+        self.assert_close(f(data), expected)
 
     def test_gradcheck(self, device, dtype):
         batch_size, channels, height, width = 2, 3, 4, 5
@@ -564,8 +628,28 @@ def test_gradcheck_with_mean_subtraction(self, device, dtype):
         img = tensor_to_gradcheck_var(img)  # to var
         assert gradcheck(kornia.enhance.adjust_contrast_with_mean_subtraction, (img, 2.0), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
 
-class TestAdjustBrightness:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
+
+class TestAdjustBrightness(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 4, 4), (2, 3, 3, 3), (4, 3, 3, 1, 1)])
     def test_cardinality(self, device, dtype, shape):
         img = torch.rand(shape, device=device, dtype=dtype)
@@ -581,7 +665,7 @@ def test_factor_zero(self, device, dtype):
         )  # 3x2x2
 
         f = kornia.enhance.AdjustBrightness(0.0)
-        assert_close(f(data), data)
+        self.assert_close(f(data), data)
 
     def test_factor_saturat(self, device, dtype):
         # prepare input data
@@ -589,7 +673,7 @@ def test_factor_saturat(self, device, dtype):
         ones = torch.ones_like(data)
 
         f = kornia.enhance.AdjustBrightness(0.6)
-        assert_close(f(data), ones)
+        self.assert_close(f(data), ones)
 
     @pytest.mark.parametrize("channels", [1, 4, 5])
     def test_factor_tensor(self, device, dtype, channels):
@@ -630,7 +714,7 @@ def test_factor_tensor_color_accumulative(self, device, dtype):
         factor = torch.tensor([0.25, 0.1], device=device, dtype=dtype)
 
         f = kornia.enhance.AdjustBrightnessAccumulative(factor)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_gradcheck_additive(self, device, dtype):
         batch_size, channels, height, width = 2, 3, 4, 5
@@ -644,8 +728,33 @@ def test_gradcheck_accumulative(self, device, dtype):
         img = tensor_to_gradcheck_var(img)  # to var
         assert gradcheck(kornia.enhance.adjust_brightness_accumulative, (img, 2.0), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_gradcheck(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_jit(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
 
-class TestAdjustSigmoid:
+class TestAdjustSigmoid(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 4, 4), (2, 3, 4, 4)])
     def test_shape_sigmoid(self, shape, device):
         inputs = torch.ones(*shape, device=device)
@@ -680,7 +789,7 @@ def test_sigmoid(self, device, dtype):
         )  # 2x3x2x2
 
         f = kornia.enhance.AdjustSigmoid()
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @pytest.mark.jit
     def test_jit(self, device, dtype):
@@ -688,7 +797,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.enhance.adjust_sigmoid
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -697,8 +806,28 @@ def test_gradcheck(self, device, dtype):
         inputs = tensor_to_gradcheck_var(inputs)
         assert gradcheck(kornia.enhance.adjust_sigmoid, inputs, raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
 
-class TestAdjustLog:
+class TestAdjustLog(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 4, 4), (2, 3, 4, 4)])
     def test_shape_sigmoid(self, shape, device):
         inputs = torch.ones(*shape, device=device)
@@ -734,7 +863,7 @@ def test_log(self, device, dtype):
         )  # 2x3x2x2
 
         f = kornia.enhance.AdjustLog()
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @pytest.mark.jit
     def test_jit(self, device, dtype):
@@ -742,7 +871,7 @@ def test_jit(self, device, dtype):
         img = torch.ones(B, C, H, W, device=device, dtype=dtype)
         op = kornia.enhance.adjust_log
         op_jit = torch.jit.script(op)
-        assert_close(op(img), op_jit(img))
+        self.assert_close(op(img), op_jit(img))
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -751,8 +880,28 @@ def test_gradcheck(self, device, dtype):
         inputs = tensor_to_gradcheck_var(inputs)
         assert gradcheck(kornia.enhance.adjust_log, (inputs, 0.1), raise_exception=True)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
 
-class TestEqualize:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
+
+class TestEqualize(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 4, 4), (2, 3, 4, 4), (3, 2, 3, 3, 4, 4)])
     def test_shape_equalize(self, shape, device, dtype):
         inputs = torch.ones(*shape, device=device, dtype=dtype)
@@ -804,7 +953,7 @@ def test_equalize(self, device, dtype):
 
         f = kornia.enhance.equalize
 
-        assert_close(f(inputs), expected, rtol=1e-4, atol=1e-4)
+        self.assert_close(f(inputs), expected)
 
     def test_equalize_batch(self, device, dtype):
         bs, channels, height, width = 2, 3, 20, 20
@@ -842,7 +991,7 @@ def test_equalize_batch(self, device, dtype):
 
         f = kornia.enhance.equalize
 
-        assert_close(f(inputs), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(inputs), expected)
 
     def test_gradcheck(self, device, dtype):
         bs, channels, height, width = 1, 2, 3, 3
@@ -858,7 +1007,7 @@ def test_jit(self, device, dtype):
         op = kornia.enhance.equalize
         op_script = torch.jit.script(op)
 
-        assert_close(op(inp), op_script(inp))
+        self.assert_close(op(inp), op_script(inp))
 
     @staticmethod
     def build_input(batch_size, channels, height, width, device, dtype, row=None):
@@ -871,8 +1020,28 @@ def build_input(batch_size, channels, height, width, device, dtype, row=None):
 
         return batch
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
 
-class TestEqualize3D:
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
+
+class TestEqualize3D(BaseTester):
     @pytest.mark.parametrize("shape", [(3, 6, 10, 10), (2, 3, 6, 10, 10), (3, 2, 3, 6, 10, 10)])
     def test_shape_equalize3d(self, shape, device, dtype):
         inputs3d = torch.ones(*shape, device=device, dtype=dtype)
@@ -903,7 +1072,7 @@ def test_equalize3d(self, device, dtype):
 
         f = kornia.enhance.equalize3d
 
-        assert_close(f(inputs3d), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(inputs3d), expected)
 
     def test_equalize3d_batch(self, device, dtype):
         bs, channels, depth, height, width = 2, 3, 6, 10, 10
@@ -920,7 +1089,7 @@ def test_equalize3d_batch(self, device, dtype):
 
         f = kornia.enhance.equalize3d
 
-        assert_close(f(inputs3d), expected, atol=1e-4, rtol=1e-4)
+        self.assert_close(f(inputs3d), expected)
 
     def test_gradcheck(self, device, dtype):
         bs, channels, depth, height, width = 1, 2, 3, 4, 5
@@ -936,7 +1105,7 @@ def test_jit(self, device, dtype):
         op = kornia.enhance.equalize3d
         op_script = torch.jit.script(op)
 
-        assert_close(op(inp), op_script(inp))
+        self.assert_close(op(inp), op_script(inp))
 
     @staticmethod
     def build_input(batch_size, channels, depth, height, width, device, dtype, row=None):
@@ -950,6 +1119,26 @@ def build_input(batch_size, channels, depth, height, width, device, dtype, row=N
 
         return batch
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_module(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_smoke(self, device, dtype):
+        pass
+
 
 class TestSharpness(BaseTester):
     f = kornia.enhance.sharpness
@@ -992,8 +1181,8 @@ def test_value(self, device, dtype):
         # If factor == 1, shall return original
         # TODO(jian): add test for this case
         # assert_close(TestSharpness.f(inputs, 0.), inputs, rtol=1e-4, atol=1e-4)
-        assert_close(TestSharpness.f(inputs, 1.0), inputs, rtol=1e-4, atol=1e-4)
-        assert_close(TestSharpness.f(inputs, 0.8), expected, rtol=1e-4, atol=1e-4)
+        self.assert_close(TestSharpness.f(inputs, 1.0), inputs)
+        self.assert_close(TestSharpness.f(inputs, 0.8), expected)
 
     def test_value_batch(self, device, dtype):
         torch.manual_seed(0)
@@ -1023,11 +1212,11 @@ def test_value_batch(self, device, dtype):
         )
 
         # If factor == 1, shall return original
-        tol_val: float = utils._get_precision(device, dtype)
-        assert_close(TestSharpness.f(inputs, 1), inputs, rtol=tol_val, atol=tol_val)
-        assert_close(TestSharpness.f(inputs, torch.tensor([1.0, 1.0])), inputs, rtol=tol_val, atol=tol_val)
-        assert_close(TestSharpness.f(inputs, 0.8), expected_08, rtol=tol_val, atol=tol_val)
-        assert_close(TestSharpness.f(inputs, torch.tensor([0.8, 1.3])), expected_08_13, rtol=tol_val, atol=tol_val)
+        # tol_val: float = utils._get_precision(device, dtype)
+        self.assert_close(TestSharpness.f(inputs, 1), inputs)
+        self.assert_close(TestSharpness.f(inputs, torch.tensor([1.0, 1.0])), inputs)
+        self.assert_close(TestSharpness.f(inputs, 0.8), expected_08)
+        self.assert_close(TestSharpness.f(inputs, torch.tensor([0.8, 1.3])), expected_08_13)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -1044,7 +1233,7 @@ def test_jit(self, device, dtype):
         img = torch.rand(2, 1, 3, 3).to(device=device, dtype=dtype)
         expected = op(img, 0.8)
         actual = op_script(img, 0.8)
-        assert_close(actual, expected)
+        self.assert_close(actual, expected)
 
     # TODO: update with module when exists
     @pytest.mark.skip(reason="Not having it yet.")
@@ -1053,7 +1242,7 @@ def test_module(self, device, dtype):
         img = torch.ones(2, 3, 4, 4, device=device, dtype=dtype)
         ops = TestSharpness.f
         mod = TestSharpness.f
-        assert_close(ops(img), mod(img))
+        self.assert_close(ops(img), mod(img))
 
 
 @pytest.mark.skipif(kornia.xla_is_available(), reason="issues with xla device")
@@ -1118,7 +1307,7 @@ def test_value(self, device, dtype):
         )
 
         # TODO(jian): precision is very bad compared to PIL
-        assert_close(TestSolarize.f(inputs, 0.5), expected, rtol=1e-2, atol=1e-2)
+        self.assert_close(TestSolarize.f(inputs, 0.5), expected, low_tolerance=True)
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
@@ -1136,7 +1325,7 @@ def test_jit(self, device, dtype):
         img = torch.rand(2, 1, 3, 3).to(device=device, dtype=dtype)
         expected = op(img, 0.8)
         actual = op_script(img, 0.8)
-        assert_close(actual, expected)
+        self.assert_close(actual, expected)
 
     # TODO: update with module when exists
     @pytest.mark.skip(reason="Not having it yet.")
@@ -1145,7 +1334,7 @@ def test_module(self, device, dtype):
         img = torch.ones(2, 3, 4, 4, device=device, dtype=dtype)
         ops = TestSolarize.f
         mod = TestSolarize.f
-        assert_close(ops(img), mod(img))
+        self.assert_close(ops(img), mod(img))
 
 
 class TestPosterize(BaseTester):
@@ -1197,9 +1386,9 @@ def test_value(self, device, dtype):
             [[[[0.0, 0.50196078, 0.0], [0.0, 0.0, 0.50196078], [0.0, 0.50196078, 0.0]]]], device=device, dtype=dtype
         )
 
-        assert_close(TestPosterize.f(inputs, 1), expected)
-        assert_close(TestPosterize.f(inputs, 0), torch.zeros_like(inputs))
-        assert_close(TestPosterize.f(inputs, 8), inputs)
+        self.assert_close(TestPosterize.f(inputs, 1), expected)
+        self.assert_close(TestPosterize.f(inputs, 0), torch.zeros_like(inputs))
+        self.assert_close(TestPosterize.f(inputs, 8), inputs)
 
     @pytest.mark.skip(reason="IndexError: tuple index out of range")
     @pytest.mark.grad
@@ -1218,7 +1407,7 @@ def test_jit(self, device, dtype):
         img = torch.rand(2, 1, 3, 3).to(device=device, dtype=dtype)
         expected = op(img, 8)
         actual = op_script(img, 8)
-        assert_close(actual, expected)
+        self.assert_close(actual, expected)
 
     # TODO: update with module when exists
     @pytest.mark.skip(reason="Not having it yet.")
@@ -1227,4 +1416,4 @@ def test_module(self, device, dtype):
         img = torch.ones(2, 3, 4, 4, device=device, dtype=dtype)
         ops = TestPosterize.f
         mod = TestPosterize.f
-        assert_close(ops(img), mod(img))
+        self.assert_close(ops(img), mod(img))
diff --git a/test/enhance/test_equalization.py b/test/enhance/test_equalization.py
index 19fbd53169..b9a405d7dd 100644
--- a/test/enhance/test_equalization.py
+++ b/test/enhance/test_equalization.py
@@ -6,7 +6,7 @@
 
 from kornia import enhance
 from kornia.geometry import rotate
-from kornia.testing import BaseTester, assert_close, tensor_to_gradcheck_var
+from kornia.testing import BaseTester, tensor_to_gradcheck_var
 
 
 class TestEqualization(BaseTester):
@@ -87,7 +87,7 @@ def test_jit(self, device, dtype):
         inp = torch.rand(batch_size, channels, height, width, device=device, dtype=dtype)
         op = enhance.equalize_clahe
         op_script = torch.jit.script(op)
-        assert_close(op(inp), op_script(inp))
+        self.assert_close(op(inp), op_script(inp))
 
     def test_module(self):
         # equalize_clahe is only a function
@@ -107,7 +107,7 @@ def test_he(self, img):
         res = enhance.equalize_clahe(img, clip_limit=clip_limit, grid_size=grid_size)
         # NOTE: for next versions we need to improve the computation of the LUT
         # and test with a better image
-        assert torch.allclose(
+        self.assert_close(
             res[..., 0, :],
             torch.tensor(
                 [
@@ -139,8 +139,6 @@ def test_he(self, img):
                 dtype=res.dtype,
                 device=res.device,
             ),
-            atol=1e-04,
-            rtol=1e-04,
         )
 
     def test_ahe(self, img):
@@ -149,7 +147,7 @@ def test_ahe(self, img):
         res = enhance.equalize_clahe(img, clip_limit=clip_limit, grid_size=grid_size)
         # NOTE: for next versions we need to improve the computation of the LUT
         # and test with a better image
-        assert torch.allclose(
+        self.assert_close(
             res[..., 0, :],
             torch.tensor(
                 [
@@ -181,8 +179,6 @@ def test_ahe(self, img):
                 dtype=res.dtype,
                 device=res.device,
             ),
-            atol=1e-04,
-            rtol=1e-04,
         )
 
     def test_clahe(self, img):
@@ -252,5 +248,5 @@ def test_clahe(self, img):
             dtype=res.dtype,
             device=res.device,
         )
-        assert torch.allclose(res[..., 0, :], expected, atol=1e-04, rtol=1e-04)
-        assert torch.allclose(res_diff[..., 0, :], exp_diff, atol=1e-04, rtol=1e-04)
+        self.assert_close(res[..., 0, :], expected)
+        self.assert_close(res_diff[..., 0, :], exp_diff)
diff --git a/test/enhance/test_normalize.py b/test/enhance/test_normalize.py
index 211d3589f9..3ad9c110e4 100644
--- a/test/enhance/test_normalize.py
+++ b/test/enhance/test_normalize.py
@@ -4,10 +4,10 @@
 
 import kornia
 import kornia.testing as utils  # test utils
-from kornia.testing import BaseTester, assert_close
+from kornia.testing import BaseTester
 
 
-class TestNormalize:
+class TestNormalize(BaseTester):
     def test_smoke(self, device, dtype):
         mean = [0.5]
         std = [0.1]
@@ -25,7 +25,7 @@ def test_normalize(self, device, dtype):
         expected = torch.tensor([0.25], device=device, dtype=dtype).repeat(1, 2, 2).view_as(data)
 
         f = kornia.enhance.Normalize(mean, std)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_broadcast_normalize(self, device, dtype):
 
@@ -40,7 +40,7 @@ def test_broadcast_normalize(self, device, dtype):
         expected = torch.ones_like(data) + 1
 
         f = kornia.enhance.Normalize(mean, std)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_float_input(self, device, dtype):
 
@@ -54,7 +54,7 @@ def test_float_input(self, device, dtype):
         expected = torch.ones_like(data) + 1
 
         f = kornia.enhance.Normalize(mean, std)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_batch_normalize(self, device, dtype):
 
@@ -69,7 +69,7 @@ def test_batch_normalize(self, device, dtype):
         expected = torch.tensor([1.25, 1, 0.5], device=device, dtype=dtype).repeat(2, 1, 1).view_as(data)
 
         f = kornia.enhance.Normalize(mean, std)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @pytest.mark.skip(reason="union type not supported")
     def test_jit(self, device, dtype):
@@ -81,7 +81,7 @@ def test_jit(self, device, dtype):
         op = kornia.enhance.normalize
         op_script = torch.jit.script(op)
 
-        assert_close(op(*inputs), op_script(*inputs))
+        self.assert_close(op(*inputs), op_script(*inputs))
 
     def test_gradcheck(self, device, dtype):
         # prepare input data
@@ -104,7 +104,7 @@ def test_single_value(self, device, dtype):
         # expected output
         expected = (data - mean) / std
 
-        assert_close(kornia.enhance.normalize(data, mean, std), expected)
+        self.assert_close(kornia.enhance.normalize(data, mean, std), expected)
 
     def test_module(self, device, dtype):
         data = torch.ones(2, 3, 1, 1, device=device, dtype=dtype)
@@ -115,31 +115,39 @@ def test_module(self, device, dtype):
         op = kornia.enhance.normalize
         op_module = kornia.enhance.Normalize(mean, std)
 
-        assert_close(op(*inputs), op_module(data))
+        self.assert_close(op(*inputs), op_module(data))
 
-    @staticmethod
     @pytest.mark.parametrize(
         "mean, std", [((1.0, 1.0, 1.0), (0.5, 0.5, 0.5)), (1.0, 0.5), (torch.tensor([1.0]), torch.tensor([0.5]))]
     )
-    def test_random_normalize_different_parameter_types(mean, std):
+    def test_random_normalize_different_parameter_types(self, mean, std):
         f = kornia.enhance.Normalize(mean=mean, std=std)
         data = torch.ones(2, 3, 256, 313)
         if isinstance(mean, float):
             expected = (data - torch.as_tensor(mean)) / torch.as_tensor(std)
         else:
             expected = (data - torch.as_tensor(mean[0])) / torch.as_tensor(std[0])
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
-    @staticmethod
     @pytest.mark.parametrize("mean, std", [((1.0, 1.0, 1.0, 1.0), (0.5, 0.5, 0.5, 0.5)), ((1.0, 1.0), (0.5, 0.5))])
-    def test_random_normalize_invalid_parameter_shape(mean, std):
+    def test_random_normalize_invalid_parameter_shape(self, mean, std):
         f = kornia.enhance.Normalize(mean=mean, std=std)
         inputs = torch.arange(0.0, 16.0, step=1).reshape(1, 4, 4).unsqueeze(0)
         with pytest.raises(ValueError):
             f(inputs)
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
+
 
-class TestDenormalize:
+class TestDenormalize(BaseTester):
     def test_smoke(self, device, dtype):
         mean = [0.5]
         std = [0.1]
@@ -157,7 +165,7 @@ def test_denormalize(self, device, dtype):
         expected = torch.tensor([2.5], device=device, dtype=dtype).repeat(1, 2, 2).view_as(data)
 
         f = kornia.enhance.Denormalize(mean, std)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_broadcast_denormalize(self, device, dtype):
 
@@ -172,7 +180,7 @@ def test_broadcast_denormalize(self, device, dtype):
         expected = torch.ones_like(data) + 2.5
 
         f = kornia.enhance.Denormalize(mean, std)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_float_input(self, device, dtype):
 
@@ -186,7 +194,7 @@ def test_float_input(self, device, dtype):
         expected = torch.ones_like(data) + 2.5
 
         f = kornia.enhance.Denormalize(mean, std)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     def test_batch_denormalize(self, device, dtype):
 
@@ -201,7 +209,7 @@ def test_batch_denormalize(self, device, dtype):
         expected = torch.tensor([6.5, 7, 8], device=device, dtype=dtype).repeat(2, 1, 1).view_as(data)
 
         f = kornia.enhance.Denormalize(mean, std)
-        assert_close(f(data), expected)
+        self.assert_close(f(data), expected)
 
     @pytest.mark.skip(reason="union type not supported")
     def test_jit(self, device, dtype):
@@ -213,7 +221,7 @@ def test_jit(self, device, dtype):
         op = kornia.enhance.denormalize
         op_script = torch.jit.script(op)
 
-        assert_close(op(*inputs), op_script(*inputs))
+        self.assert_close(op(*inputs), op_script(*inputs))
 
     def test_gradcheck(self, device, dtype):
 
@@ -239,7 +247,7 @@ def test_single_value(self, device, dtype):
         # expected output
         expected = (data * std) + mean
 
-        assert_close(kornia.enhance.denormalize(data, mean, std), expected)
+        self.assert_close(kornia.enhance.denormalize(data, mean, std), expected)
 
     def test_module(self, device, dtype):
         data = torch.ones(2, 3, 1, 1, device=device, dtype=dtype)
@@ -250,7 +258,17 @@ def test_module(self, device, dtype):
         op = kornia.enhance.denormalize
         op_module = kornia.enhance.Denormalize(mean, std)
 
-        assert_close(op(*inputs), op_module(data))
+        self.assert_close(op(*inputs), op_module(data))
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_cardinality(self, device, dtype):
+        pass
+
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
+    def test_exception(self, device, dtype):
+        pass
 
 
 class TestNormalizeMinMax(BaseTester):
@@ -279,8 +297,8 @@ def test_cardinality(self, device, dtype, input_shape):
     def test_range(self, device, dtype, min_val, max_val):
         x = torch.rand(1, 2, 4, 5, device=device, dtype=dtype)
         out = kornia.enhance.normalize_min_max(x, min_val=min_val, max_val=max_val)
-        assert_close(out.min().item(), min_val)
-        assert_close(out.max().item(), max_val)
+        self.assert_close(out.min(), torch.tensor(min_val))
+        self.assert_close(out.max(), torch.tensor(max_val))
 
     def test_values(self, device, dtype):
         x = torch.tensor([[[[0.0, 1.0, 3.0], [-1.0, 4.0, 3.0], [9.0, 5.0, 2.0]]]], device=device, dtype=dtype)
@@ -290,14 +308,14 @@ def test_values(self, device, dtype):
         )
 
         actual = kornia.enhance.normalize_min_max(x, min_val=-1.0, max_val=1.0)
-        assert_close(actual, expected, atol=1e-6, rtol=1e-6)
+        self.assert_close(actual, expected)
 
     @pytest.mark.jit
     def test_jit(self, device, dtype):
         x = torch.ones(1, 1, 1, 1, device=device, dtype=dtype)
         op = kornia.enhance.normalize_min_max
         op_jit = torch.jit.script(op)
-        assert_close(op(x), op_jit(x))
+        self.assert_close(op(x), op_jit(x))
 
     @pytest.mark.grad
     def test_gradcheck(self, device, dtype):
diff --git a/test/losses/test_losses.py b/test/losses/test_losses.py
index 809f3d1f2c..cf83116c29 100644
--- a/test/losses/test_losses.py
+++ b/test/losses/test_losses.py
@@ -74,11 +74,11 @@ def test_jit(self, device, dtype):
         expected = op(logits, labels, alpha=0.5, gamma=2.0, reduction="none")
         assert_close(actual, expected)
 
-    def test_gradcheck(self, device):
+    def test_gradcheck(self, device, dtype):
         alpha, gamma = 0.5, 2.0  # for focal loss with logits
-        logits = torch.rand(2, 3, 2).to(device)
+        logits = torch.rand(2, 3, 2).to(device, dtype)
         labels = torch.rand(2, 1, 3, 2)
-        labels = labels.to(device).long()
+        labels = labels.to(device, dtype).long()
 
         logits = utils.tensor_to_gradcheck_var(logits)  # to var
         assert gradcheck(
@@ -329,7 +329,8 @@ class TestDivergenceLoss:
     )
     def test_js_div_loss_2d(self, device, dtype, input, target, expected):
         actual = kornia.losses.js_div_loss_2d(input.to(device, dtype), target.to(device, dtype))
-        assert_close(actual.item(), expected)
+        expected = torch.tensor(expected).to(device, dtype)
+        assert_close(actual, expected)
 
     @pytest.mark.parametrize(
         'input,target,expected',
@@ -342,7 +343,8 @@ def test_js_div_loss_2d(self, device, dtype, input, target, expected):
     )
     def test_kl_div_loss_2d(self, device, dtype, input, target, expected):
         actual = kornia.losses.kl_div_loss_2d(input.to(device, dtype), target.to(device, dtype))
-        assert_close(actual.item(), expected)
+        expected = torch.tensor(expected).to(device, dtype)
+        assert_close(actual, expected)
 
     @pytest.mark.parametrize(
         'input,target,expected',
@@ -369,7 +371,8 @@ def test_kl_div_loss_2d_without_reduction(self, device, dtype, input, target, ex
     def test_noncontiguous_kl(self, device, dtype, input, target, expected):
         input = input.to(device, dtype).view(input.shape[::-1]).T
         target = target.to(device, dtype).view(target.shape[::-1]).T
-        actual = kornia.losses.kl_div_loss_2d(input, target).item()
+        actual = kornia.losses.kl_div_loss_2d(input, target)
+        expected = torch.tensor(expected).to(device, dtype)
         assert_close(actual, expected)
 
     @pytest.mark.parametrize(
@@ -384,7 +387,8 @@ def test_noncontiguous_kl(self, device, dtype, input, target, expected):
     def test_noncontiguous_js(self, device, dtype, input, target, expected):
         input = input.to(device, dtype).view(input.shape[::-1]).T
         target = target.to(device, dtype).view(target.shape[::-1]).T
-        actual = kornia.losses.js_div_loss_2d(input, target).item()
+        actual = kornia.losses.js_div_loss_2d(input, target)
+        expected = torch.tensor(expected).to(device, dtype)
         assert_close(actual, expected)
 
     def test_gradcheck_kl(self, device, dtype):


Code review comments:
diff_hunk: @@ -961,8 +961,33 @@ def test_random_vflip_coord_check(self, device, dtype):
             == input[..., input_coordinates[0, 1, :], input_coordinates[0, 0, :]]
         ).all()
 
+    @pytest.mark.skip(reason="not implemented yet")
+    @pytest.mark.nn
path: test/augmentation/test_augmentation.py
text: @user1:
```suggestion
```
not very clear we need this anymore, unless we find a real utility

@author:
Thanks for noticing, i will fix it everywhere

diff_hunk: @@ -76,30 +76,44 @@ def create_random_fundamental_matrix(batch_size, std_val=1e-3):
 
 
 class BaseTester(ABC):
+    DTYPE_PRECISIONS = {torch.float16: (1e-2, 1e-3), torch.float32: (1e-4, 1e-4), torch.float64: (1e-5, 1e-8)}
+
     @abstractmethod
-    def test_smoke(self):
+    def test_smoke(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_exception(self):
+    def test_exception(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_cardinality(self):
+    def test_cardinality(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_jit(self):
+    def test_jit(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_gradcheck(self):
+    def test_gradcheck(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_module(self):
+    def test_module(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
+    def assert_close(self, actual: torch.Tensor, expected: torch.Tensor, low_tolerance: bool = False) -> None:
path: kornia/testing/__init__.py
text: @user1:
```suggestion
    def assert_close(self, actual: Tensor, expected: Tensor, low_tolerance: bool = False) -> None:
```
`from kornia.core import Tensor`

diff_hunk: @@ -76,30 +76,44 @@ def create_random_fundamental_matrix(batch_size, std_val=1e-3):
 
 
 class BaseTester(ABC):
+    DTYPE_PRECISIONS = {torch.float16: (1e-2, 1e-3), torch.float32: (1e-4, 1e-4), torch.float64: (1e-5, 1e-8)}
+
     @abstractmethod
-    def test_smoke(self):
+    def test_smoke(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_exception(self):
+    def test_exception(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_cardinality(self):
+    def test_cardinality(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_jit(self):
+    def test_jit(self, device, dtype):
         raise NotImplementedError("Implement a stupid routine.")
 
     @abstractmethod
-    def test_gradcheck(self):
+    def test_gradcheck(self, device, dtype):
path: kornia/testing/__init__.py
text: @user1:
```suggestion
    def test_gradcheck(self, device):
```
I believe that for `gradcheck` we should test for `torch.float64`