Repository: TREX-CoE/trexio (language: python)

Issue:
Loss of precision in Python
I wrote the nuclear repulsion in a TREXIO file. The nuclear repulsion computed by quantum package is
```
* Nuclear repulsion energy                           9.189533758614488    
```

I store it in a TREXIO file, and when I read it back in Python I get:
```
trexio.read_nucleus_repulsion(f)
9.189534187316895
 ```


The value given by Python is the same with both the text and the HDF5 back-ends.

When I inspect the text files produced by the text backend, I can see that the value of the nuclear repulsion is correct:
```
nucleus_repulsion   9.1895337586144876e+00                                                   
```

So I believe there is a conversion from float64 to float32 in the python interface after reading, but I could not figure out where it comes from...

It seems that I get the problem only for scalars. Arrays seem to be OK.



Discussion / hints:

Fix patch:
diff --git a/src/templates_front/templator_front.org b/src/templates_front/templator_front.org
index 5db927f6..c3f692f9 100644
--- a/src/templates_front/templator_front.org
+++ b/src/templates_front/templator_front.org
@@ -740,7 +740,6 @@ typedef struct trexio_s trexio_t;
 
    #+begin_src c :tangle prefix_s_front.h
 struct trexio_s {
-  char              file_name[TREXIO_MAX_FILENAME_LENGTH];
   pthread_mutex_t   thread_lock;
   back_end_t        back_end;
   char              mode;
@@ -750,6 +749,7 @@ struct trexio_s {
   int16_t           version_minor;
   int16_t           version_patch;
   char              version[16];
+  char              file_name[TREXIO_MAX_FILENAME_LENGTH];
 };
    #+end_src
 
diff --git a/src/templates_hdf5/templator_hdf5.org b/src/templates_hdf5/templator_hdf5.org
index ac684755..3b63abaf 100644
--- a/src/templates_hdf5/templator_hdf5.org
+++ b/src/templates_hdf5/templator_hdf5.org
@@ -497,7 +497,8 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
   trexio_hdf5_t* f = (trexio_hdf5_t*) file;
 
   hid_t index_dtype;
-  void* index_p = NULL;
+  const void* index_p = NULL;
+  void* index_p_non_const = NULL;
   uint64_t size_ranked = (uint64_t) size * $group_dset_rank$;
   /* Determine the optimal type for storing indices depending on the size_max (usually mo_num or ao_num) */
   if (size_max < UINT8_MAX) {
@@ -507,6 +508,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
       index[i] = (uint8_t) index_sparse[i];
     }
     index_p = index;
+    index_p_non_const = index;
     index_dtype = H5T_NATIVE_UINT8;
   } else if (size_max < UINT16_MAX) {
     uint16_t* index = CALLOC(size_ranked, uint16_t);
@@ -515,9 +517,10 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
       index[i] = (uint16_t) index_sparse[i];
     }
     index_p = index;
+    index_p_non_const = index;
     index_dtype = H5T_NATIVE_UINT16;
   } else {
-    index_p = (int32_t*) index_sparse;
+    index_p = index_sparse;
     index_dtype = H5T_NATIVE_INT32;
   }
 
@@ -541,7 +544,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
 
   /* Create chunked dataset with index_dtype datatype and write indices into it */
     rc_write = trexio_hdf5_create_write_dset_sparse(f->$group$_group, dset_index_name, index_dtype, chunk_i_dims, index_p);
-    if (index_p != index_sparse) FREE(index_p);
+    if (index_p != index_sparse) FREE(index_p_non_const);
     if (rc_write != TREXIO_SUCCESS) return rc_write;
 
   /* Create chunked dataset with value_dtype datatype and write values into it */
@@ -555,7 +558,7 @@ trexio_hdf5_write_$group_dset$ (trexio_t* const file,
 
   /* Create chunked dataset with index_dtype datatype and write indices into it */
     rc_write = trexio_hdf5_open_write_dset_sparse(f->$group$_group, dset_index_name, index_dtype, chunk_i_dims, offset_i, index_p);
-    if (index_p != index_sparse) FREE(index_p);
+    if (index_p != index_sparse) FREE(index_p_non_const);
     if (rc_write != TREXIO_SUCCESS) return rc_write;
 
   /* Create chunked dataset with value_dtype datatype and write values into it */
@@ -694,7 +697,7 @@ trexio_exit_code trexio_hdf5_read_$group_dset$(trexio_t* const file,
   if (eof_read_size == NULL) return TREXIO_INVALID_ARG_5;
   if (dset == NULL) return TREXIO_INVALID_ARG_6;
 
-  const char dset_name[256] = "$group_dset$";
+  const char* dset_name = "$group_dset$";
 
   const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
 
@@ -718,7 +721,7 @@ trexio_exit_code trexio_hdf5_write_$group_dset$(trexio_t* const file,
   if (file == NULL) return TREXIO_INVALID_ARG_1;
   if (dset == NULL) return TREXIO_INVALID_ARG_5;
 
-  const char dset_name[256] = "$group_dset$";
+  const char* dset_name = "$group_dset$";
 
   trexio_hdf5_t* f = (trexio_hdf5_t*) file;
 
@@ -756,7 +759,7 @@ trexio_hdf5_read_$group_dset$_size (trexio_t* const file, int64_t* const size_ma
   if (file == NULL) return TREXIO_INVALID_ARG_1;
   if (size_max == NULL) return TREXIO_INVALID_ARG_2;
 
-  const char dset_name[256] = "$group_dset$";
+  const char* dset_name = "$group_dset$";
 
   const trexio_hdf5_t* f = (const trexio_hdf5_t*) file;
 
@@ -792,7 +795,7 @@ trexio_exit_code trexio_hdf5_has_$group_dset$(trexio_t* const file)
   trexio_hdf5_t* f = (trexio_hdf5_t*) file;
   if (f->$group$_group == (hsize_t) 0) return TREXIO_HAS_NOT;
 
-  const char dset_name[256] = "$group_dset$";
+  const char* dset_name = "$group_dset$";
 
   htri_t exists = H5Lexists(f->$group$_group, dset_name, H5P_DEFAULT);
   if (exists > 0) {
@@ -1465,8 +1468,6 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
       uint16_t* index = CALLOC(size_ranked, uint16_t);
       if (index == NULL) return TREXIO_ALLOCATION_FAILED;
       index_p = index;
-    } else {
-      index_p = data_sparse;
     }
   }
 
@@ -1474,7 +1475,7 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
   if (status < 0) {
     H5Sclose(fspace_id);
     H5Dclose(dset_id);
-    if (index_p != data_sparse) FREE(index_p);
+    if (index_p != NULL) FREE(index_p);
     return TREXIO_INVALID_ID;
   }
 
@@ -1482,15 +1483,22 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
   if (memspace_id < 0) {
     H5Sclose(fspace_id);
     H5Dclose(dset_id);
-    if (index_p != data_sparse) FREE(index_p);
+    if (index_p != NULL) FREE(index_p);
     return TREXIO_INVALID_ID;
   }
 
   if (is_index == 1) {
-    status = H5Dread(dset_id,
-                     dtype,
-                     memspace_id, fspace_id, H5P_DEFAULT,
-                     index_p);
+    if (index_p != NULL) {
+      status = H5Dread(dset_id,
+                       dtype,
+                       memspace_id, fspace_id, H5P_DEFAULT,
+                       index_p);
+    } else {
+      status = H5Dread(dset_id,
+                       dtype,
+                       memspace_id, fspace_id, H5P_DEFAULT,
+                       data_sparse);
+    }
   } else {
     status = H5Dread(dset_id,
                      dtype,
@@ -1502,7 +1510,7 @@ trexio_hdf5_open_read_dset_sparse (const hid_t group_id,
   H5Sclose(memspace_id);
   H5Dclose(dset_id);
   if (status < 0) {
-    if (index_p != data_sparse) FREE(index_p);
+    if (index_p != NULL) FREE(index_p);
     return TREXIO_FAILURE;
   }
 


Test patch:
diff --git a/tests/delete_group.c b/tests/delete_group.c
new file mode 100644
index 00000000..8836fe19
--- /dev/null
+++ b/tests/delete_group.c
@@ -0,0 +1,85 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int test_write_delete_group (const char* file_name, const back_end_t backend) {
+
+/* Try to write a dimensioning attribute (num variable) into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 12;
+  double coord[36] = {
+  0.00000000 ,  1.39250319 ,  0.00000000 ,
+ -1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -1.20594314 , -0.69625160 ,  0.00000000 ,
+  0.00000000 , -1.39250319 ,  0.00000000 ,
+  1.20594314 , -0.69625160 ,  0.00000000 ,
+  1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -2.14171677 ,  1.23652075 ,  0.00000000 ,
+ -2.14171677 , -1.23652075 ,  0.00000000 ,
+  0.00000000 , -2.47304151 ,  0.00000000 ,
+  2.14171677 , -1.23652075 ,  0.00000000 ,
+  2.14171677 ,  1.23652075 ,  0.00000000 ,
+  0.00000000 ,  2.47304151 ,  0.00000000 ,
+  };
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // write numerical attribute in an empty file
+  rc = trexio_write_nucleus_num(file, num);
+  assert (rc == TREXIO_SUCCESS);
+
+  // write numerical dataset in a file
+  rc = trexio_write_nucleus_coord(file, coord);
+  assert (rc == TREXIO_SUCCESS);
+
+  // write numerical attribute ao_cartesian as 0
+  rc = trexio_write_ao_cartesian(file, 0);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // open file in 'unsafe' mode
+  file = trexio_open(file_name, 'u', backend, &rc);
+  assert (file != NULL);
+
+  // delete a previously written group
+  rc = trexio_delete_nucleus(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write_delete_group (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
diff --git a/tests/delete_group_hdf5.c b/tests/delete_group_hdf5.c
index 151a73a8..db03b5e3 100644
--- a/tests/delete_group_hdf5.c
+++ b/tests/delete_group_hdf5.c
@@ -1,89 +1,4 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_del.h5"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE
-
-static int test_write_delete_group (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dimensioning attribute (num variable) into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  double coord[36] = {
-  0.00000000 ,  1.39250319 ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000 ,
-  1.20594314 ,  0.69625160 ,  0.00000000 ,
- -2.14171677 ,  1.23652075 ,  0.00000000 ,
- -2.14171677 , -1.23652075 ,  0.00000000 ,
-  0.00000000 , -2.47304151 ,  0.00000000 ,
-  2.14171677 , -1.23652075 ,  0.00000000 ,
-  2.14171677 ,  1.23652075 ,  0.00000000 ,
-  0.00000000 ,  2.47304151 ,  0.00000000 ,
-  };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write numerical dataset in a file
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write numerical attribute ao_cartesian as 0
-  rc = trexio_write_ao_cartesian(file, 0);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // open file in 'unsafe' mode
-  file = trexio_open(file_name, 'u', backend, &rc);
-  assert (file != NULL);
-
-  // delete a previously written group
-  rc = trexio_delete_nucleus(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_delete_group (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "delete_group"
+#include "test_macros.h"
+#include "delete_group.c"
diff --git a/tests/delete_group_text.c b/tests/delete_group_text.c
index 37f338bb..db03b5e3 100644
--- a/tests/delete_group_text.c
+++ b/tests/delete_group_text.c
@@ -1,89 +1,4 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_del.dir"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write_delete_group (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dimensioning attribute (num variable) into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  double coord[36] = {
-  0.00000000 ,  1.39250319 ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000 ,
-  1.20594314 ,  0.69625160 ,  0.00000000 ,
- -2.14171677 ,  1.23652075 ,  0.00000000 ,
- -2.14171677 , -1.23652075 ,  0.00000000 ,
-  0.00000000 , -2.47304151 ,  0.00000000 ,
-  2.14171677 , -1.23652075 ,  0.00000000 ,
-  2.14171677 ,  1.23652075 ,  0.00000000 ,
-  0.00000000 ,  2.47304151 ,  0.00000000 ,
-  };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write numerical dataset in a file
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write numerical attribute ao_cartesian as 0
-  rc = trexio_write_ao_cartesian(file, 0);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // open file in 'unsafe' mode
-  file = trexio_open(file_name, 'u', backend, &rc);
-  assert (file != NULL);
-
-  // delete a previously written group
-  rc = trexio_delete_nucleus(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_delete_group (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "delete_group"
+#include "test_macros.h"
+#include "delete_group.c"
diff --git a/tests/io_determinant.c b/tests/io_determinant.c
new file mode 100644
index 00000000..bd861d2a
--- /dev/null
+++ b/tests/io_determinant.c
@@ -0,0 +1,322 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define SIZE          100
+#define N_CHUNKS      5
+#define STATE_TEST    2
+
+static int test_write_determinant (const char* file_name, const back_end_t backend, const int64_t offset, const int mo_num) {
+
+/* Try to write an array of sparse data into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // parameters to be written
+  int64_t* det_list;
+  double*  det_coef;
+
+  // write mo_num which will be used to determine the optimal size of int indices
+  if (trexio_has_mo_num(file) == TREXIO_HAS_NOT) {
+    rc = trexio_write_mo_num(file, mo_num);
+    assert(rc == TREXIO_SUCCESS);
+  }
+
+  // get the number of int64 bit fields per determinant
+  int int_num;
+  rc = trexio_get_int64_num(file, &int_num);
+  assert(rc == TREXIO_SUCCESS);
+  assert(int_num == (mo_num-1)/64 + 1);
+
+  // allocate memory and fill with values to be written
+  det_list = (int64_t*) calloc(2 * int_num * SIZE, sizeof(int64_t));
+  det_coef = (double*) calloc(SIZE, sizeof(double));
+
+  int64_t size_list = TREXIO_NORB_PER_INT * int_num;
+  const int32_t orb_list_up[4] = {0,1,2,3};
+  const int32_t orb_list_dn[3] = {0,1,2};
+
+
+  for(int i=0; i<SIZE; i++){
+    rc = trexio_to_bitfield_list (orb_list_up, 4, &(det_list[2*int_num*i]), int_num);
+    rc = trexio_to_bitfield_list (orb_list_dn, 3, &(det_list[2*int_num*i+int_num]), int_num);
+    det_coef[i]     = 3.14 + (double) i;
+  }
+
+  // write dataset chunks of sparse data in the file (including FAKE statements)
+  uint64_t chunk_size = (uint64_t) SIZE/N_CHUNKS;
+  uint64_t offset_f = 0UL;
+  uint64_t offset_d = 0UL;
+  if (offset != 0L) offset_f += offset;
+
+  // write the state_id of a given file: 0 is ground state
+  if (trexio_has_state_id(file) == TREXIO_HAS_NOT) {
+    rc = trexio_write_state_id(file, STATE_TEST);
+    assert(rc == TREXIO_SUCCESS);
+  }
+
+  // write n_chunks times using write_sparse
+  for(int i=0; i<N_CHUNKS; ++i){
+
+    rc = trexio_write_determinant_list(file, offset_f, chunk_size, &det_list[2*int_num*offset_d]);
+    assert(rc == TREXIO_SUCCESS);
+
+    rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
+    assert(rc == TREXIO_SUCCESS);
+
+    offset_d += chunk_size;
+    offset_f += chunk_size;
+  }
+
+  // manually check the consistency of the determinant_num and coefficient_size after writing
+  int64_t coeff_size = 0L;
+  int64_t determinant_num = 0L;
+
+  rc = trexio_read_determinant_num_64(file, &determinant_num);
+  assert(rc == TREXIO_SUCCESS);
+
+  rc = trexio_read_determinant_coefficient_size(file, &coeff_size);
+  assert(rc == TREXIO_SUCCESS);
+  assert(determinant_num == coeff_size);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // free the allocated memeory
+  free(det_list);
+  free(det_coef);
+  printf("write determinants OK\n");
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+static int test_has_determinant(const char* file_name, const back_end_t backend) {
+
+/* Try to check the existence of a dataset of sparse data in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // now check that previously written determinant_list exists
+  rc = trexio_has_determinant_list(file);
+  assert(rc==TREXIO_SUCCESS);
+
+  rc = trexio_has_state_id(file);
+  assert(rc==TREXIO_SUCCESS);
+
+  // now check that previously written determinant_coefficient exists
+  rc = trexio_has_determinant_coefficient(file);
+  assert(rc==TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+  printf("has_determinant OK\n");
+
+  return 0;
+}
+
+static int test_read_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
+
+/* Try to read one chunk of dataset of sparse data in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // compute how many integer bit fields is needed per determinant (for a given spin)
+  int64_t mo_num;
+  rc = trexio_read_mo_num_64(file, &mo_num);
+  assert (rc == TREXIO_SUCCESS);
+
+  int int_num;
+  rc = trexio_get_int64_num(file, &int_num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (int_num == (mo_num - 1)/64 + 1);
+
+  // define arrays to read into
+  int64_t* det_list_read;
+  double*  det_coef_read;
+  double check_diff;
+  uint64_t size_r = 40L;
+
+  det_list_read = (int64_t*) calloc(2*int_num*size_r,sizeof(int64_t));
+  det_coef_read = (double*)  calloc(size_r,sizeof(double));
+
+  // specify the read parameters, here:
+  // 1 chunk of 10 elements using offset of 40 (i.e. lines No. 40--59) into elements of the array starting from 5
+  int64_t chunk_read = 10L;
+  int64_t offset_file_read = 40L;
+  int offset_data_read = 5;
+  int64_t read_size_check;
+  read_size_check = chunk_read;
+
+  if (offset != 0L) offset_file_read += offset;
+
+  // read one chunk using the aforementioned parameters
+  printf("int_num: %d\n", int_num);
+  rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
+  assert(rc == TREXIO_SUCCESS);
+  assert(chunk_read == read_size_check);
+  assert(det_list_read[2*int_num*offset_data_read] == 15);
+  assert(det_list_read[2*int_num*offset_data_read+int_num] == 7);
+
+  rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
+  assert(rc == TREXIO_SUCCESS);
+  assert(chunk_read == read_size_check);
+
+  check_diff = det_coef_read[0] - 0.;
+  assert(check_diff*check_diff < 1e-14);
+
+  check_diff = det_coef_read[offset_data_read] - (3.14 + (double) (offset_file_read-offset));
+  //printf("%lf %lf\n", check_diff, det_coef_read[offset_data_read]);
+  assert(check_diff*check_diff < 1e-14);
+
+  int32_t state_id = 666;
+  rc = trexio_read_state_id(file, &state_id);
+  assert(rc == TREXIO_SUCCESS);
+  assert(state_id == STATE_TEST);
+
+  // now attempt to read so that one encounters end of file during reading (i.e. offset_file_read + chunk_read > size_max)
+  offset_file_read = 97L;
+  offset_data_read = 1;
+  int64_t eof_read_size_check = SIZE - offset_file_read; // if offset_file_read=97 => only 3 integrals will be read out of total of 100
+
+  if (offset != 0L) offset_file_read += offset;
+
+  chunk_read = read_size_check;
+  // read one chunk that will reach EOF and return TREXIO_END code
+  rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
+  /*
+  printf("%s\n", trexio_string_of_error(rc));
+  for (int i=0; i<size_r; i++) {
+    printf("%lld %lld\n", det_list_read[6*i], det_list_read[6*i+5]);
+  }
+  */
+  assert(rc == TREXIO_END);
+  assert(chunk_read == eof_read_size_check);
+
+  chunk_read = read_size_check;
+  rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
+  /*
+  printf("%s\n", trexio_string_of_error(rc));
+  for (int i=0; i<size_r; i++) {
+    printf("%lf\n", det_coef_read[i]);
+  }
+  */
+  assert(rc == TREXIO_END);
+  assert(chunk_read == eof_read_size_check);
+
+  check_diff= det_coef_read[size_r-1] - 0.;
+  //printf("%lf %lf\n", check_diff, det_coef_read[size_r-1]);
+  assert(check_diff*check_diff < 1e-14);
+
+  // check the value of determinant_num
+  int32_t det_num = 0;
+  int32_t size_check = SIZE;
+  if (offset != 0L) size_check += offset;
+
+  rc = trexio_read_determinant_num(file, &det_num);
+  assert(rc == TREXIO_SUCCESS);
+  assert(det_num == size_check);
+
+  // check conversion of determinants into orbital lists
+  int64_t  size_list = TREXIO_NORB_PER_INT * int_num;
+  int32_t* orb_list_up = (int32_t*) calloc(size_list, sizeof(int32_t));
+  int32_t* orb_list_dn = (int32_t*) calloc(size_list, sizeof(int32_t));
+  int32_t  occ_num_up, occ_num_dn;
+
+  rc = trexio_read_determinant_list(file, 0L, &chunk_read, &det_list_read[0L]);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_to_orbital_list_up_dn (int_num, &det_list_read[0], orb_list_up, orb_list_dn, &occ_num_up, &occ_num_dn);
+  assert (rc == TREXIO_SUCCESS);
+  assert (occ_num_up == 4);
+  assert (occ_num_dn == 3);
+  // DEBUG printing
+  for (int i=0; i<occ_num_up; i++) {
+     assert(orb_list_up[i] == i);
+  }
+  for (int i=0; i<occ_num_dn; i++) {
+     assert(orb_list_dn[i] == i);
+  }
+
+  // check conversion of one orbital list into the bitfield determinant representation
+  int64_t* det_list_check = (int64_t*) calloc(int_num, sizeof(int64_t));
+
+  rc = trexio_to_bitfield_list (orb_list_up, occ_num_up, det_list_check, int_num);
+  assert (rc == TREXIO_SUCCESS);
+  for (int i=0; i<int_num; i++) {
+    assert (det_list_check[i] == det_list_read[2*int_num*5+i]);
+  }
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // free the memory
+  free(det_list_read);
+  free(det_coef_read);
+  free(det_list_check);
+  free(orb_list_up);
+  free(orb_list_dn);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(){
+
+/*============== Test launcher ================*/
+
+  int mo_nums[5] = {10, 20, 40, 100, 300};
+  for (int i=0 ; i<5 ; ++i) {
+    int rc = system(RM_COMMAND);
+    assert (rc == 0);
+
+  // check the first write attempt (SIZE elements written in N_CHUNKS chunks)
+    printf("mo_num = %d\n", mo_nums[i]);
+    test_write_determinant (TREXIO_FILE, TEST_BACKEND, 0L, mo_nums[i]);
+    test_has_determinant   (TREXIO_FILE, TEST_BACKEND);
+    test_read_determinant  (TREXIO_FILE, TEST_BACKEND, 0L);
+
+    // check the second write attempt (SIZE elements written in N_CHUNKS chunks)
+    test_write_determinant (TREXIO_FILE, TEST_BACKEND, (int64_t) SIZE, mo_nums[i]);
+    test_read_determinant  (TREXIO_FILE, TEST_BACKEND, (int64_t) SIZE);
+
+    rc = system(RM_COMMAND);
+    assert (rc == 0);
+  }
+
+  return 0;
+}
diff --git a/tests/io_determinant_hdf5.c b/tests/io_determinant_hdf5.c
index 5538680a..35dcb929 100644
--- a/tests/io_determinant_hdf5.c
+++ b/tests/io_determinant_hdf5.c
@@ -1,326 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_determinant"
+#include "test_macros.h"
+#include "io_determinant.c"
 
-#define TEST_BACKEND  TREXIO_HDF5
-#define TREXIO_FILE   "test_determinant.h5"
-#define RM_COMMAND    "rm -f -- " TREXIO_FILE
-#define SIZE          100
-#define N_CHUNKS      5
-#define STATE_TEST    2
-#define MO_NUM        150
-
-static int test_write_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
-
-/* Try to write an array of sparse data into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // parameters to be written
-  int64_t* det_list;
-  double*  det_coef;
-
-  int mo_num = MO_NUM;
-
-  // write mo_num which will be used to determine the optimal size of int indices
-  if (trexio_has_mo_num(file) == TREXIO_HAS_NOT) {
-    rc = trexio_write_mo_num(file, mo_num);
-    assert(rc == TREXIO_SUCCESS);
-  }
-
-  // get the number of int64 bit fields per determinant
-  int int_num;
-  rc = trexio_get_int64_num(file, &int_num);
-  assert(rc == TREXIO_SUCCESS);
-  assert(int_num == (MO_NUM-1)/64 + 1);
-
-  // allocate memory and fill with values to be written
-  det_list = (int64_t*) calloc(2 * int_num * SIZE, sizeof(int64_t));
-  det_coef = (double*) calloc(SIZE, sizeof(double));
-
-  for(int i=0; i<SIZE; i++){
-    det_list[6*i]   = 6*i;
-    det_list[6*i+1] = 6*i+1;
-    det_list[6*i+2] = 6*i+2;
-    det_list[6*i+3] = 6*i+3;
-    det_list[6*i+4] = 6*i+4;
-    det_list[6*i+5] = 6*i+5;
-    det_coef[i]     = 3.14 + (double) i;
-  }
-
-  // write dataset chunks of sparse data in the file (including FAKE statements)
-  uint64_t chunk_size = (uint64_t) SIZE/N_CHUNKS;
-  uint64_t offset_f = 0UL;
-  uint64_t offset_d = 0UL;
-  if (offset != 0L) offset_f += offset;
-
-  // write the state_id of a given file: 0 is ground state
-  if (trexio_has_state_id(file) == TREXIO_HAS_NOT) {
-    rc = trexio_write_state_id(file, STATE_TEST);
-    assert(rc == TREXIO_SUCCESS);
-  }
-
-  // write n_chunks times using write_sparse
-  for(int i=0; i<N_CHUNKS; ++i){
-
-    rc = trexio_write_determinant_list(file, offset_f, chunk_size, &det_list[2*int_num*offset_d]);
-    assert(rc == TREXIO_SUCCESS);
-
-    rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
-    assert(rc == TREXIO_SUCCESS);
-
-    offset_d += chunk_size;
-    offset_f += chunk_size;
-  }
-
-  // manually check the consistency of the determinant_num and coefficient_size after writing
-  int64_t coeff_size = 0L;
-  int64_t determinant_num = 0L;
-
-  rc = trexio_read_determinant_num_64(file, &determinant_num);
-  assert(rc == TREXIO_SUCCESS);
-
-  rc = trexio_read_determinant_coefficient_size(file, &coeff_size);
-  assert(rc == TREXIO_SUCCESS);
-  assert(determinant_num == coeff_size);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // free the allocated memeory
-  free(det_list);
-  free(det_coef);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_has_determinant(const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // now check that previously written determinant_list exists
-  rc = trexio_has_determinant_list(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  rc = trexio_has_state_id(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // now check that previously written determinant_coefficient exists
-  rc = trexio_has_determinant_coefficient(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_read_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
-
-/* Try to read one chunk of dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // compute how many integer bit fields is needed per determinant (for a given spin)
-  int64_t mo_num;
-  rc = trexio_read_mo_num_64(file, &mo_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (mo_num == MO_NUM);
-
-  int int_num;
-  rc = trexio_get_int64_num(file, &int_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (int_num == (MO_NUM - 1)/64 + 1);
-
-  // define arrays to read into
-  int64_t* det_list_read;
-  double*  det_coef_read;
-  double check_diff;
-  uint64_t size_r = 40L;
-
-  det_list_read = (int64_t*) calloc(2*int_num*size_r,sizeof(int64_t));
-  det_coef_read = (double*)  calloc(size_r,sizeof(double));
-
-  // specify the read parameters, here:
-  // 1 chunk of 10 elements using offset of 40 (i.e. lines No. 40--59) into elements of the array starting from 5
-  int64_t chunk_read = 10L;
-  int64_t offset_file_read = 40L;
-  int offset_data_read = 5;
-  int64_t read_size_check;
-  read_size_check = chunk_read;
-
-  if (offset != 0L) offset_file_read += offset;
-
-  // read one chunk using the aforementioned parameters
-  rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
-  assert(rc == TREXIO_SUCCESS);
-  assert(chunk_read == read_size_check);
-  assert(det_list_read[0] == 0);
-  assert(det_list_read[2*int_num*offset_data_read] == 2 * int_num * (int64_t) (offset_file_read-offset));
-
-  rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
-  assert(rc == TREXIO_SUCCESS);
-  assert(chunk_read == read_size_check);
-
-  check_diff = det_coef_read[0] - 0.;
-  assert(check_diff*check_diff < 1e-14);
-
-  check_diff = det_coef_read[offset_data_read] - (3.14 + (double) (offset_file_read-offset));
-  //printf("%lf %lf\n", check_diff, det_coef_read[offset_data_read]);
-  assert(check_diff*check_diff < 1e-14);
-
-  int32_t state_id = 666;
-  rc = trexio_read_state_id(file, &state_id);
-  assert(rc == TREXIO_SUCCESS);
-  assert(state_id == STATE_TEST);
-
-  // now attempt to read so that one encounters end of file during reading (i.e. offset_file_read + chunk_read > size_max)
-  offset_file_read = 97L;
-  offset_data_read = 1;
-  int64_t eof_read_size_check = SIZE - offset_file_read; // if offset_file_read=97 => only 3 integrals will be read out of total of 100
-
-  if (offset != 0L) offset_file_read += offset;
-
-  chunk_read = read_size_check;
-  // read one chunk that will reach EOF and return TREXIO_END code
-  rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
-  /*
-  printf("%s\n", trexio_string_of_error(rc));
-  for (int i=0; i<size_r; i++) {
-    printf("%lld %lld\n", det_list_read[6*i], det_list_read[6*i+5]);
-  }
-  */
-  assert(rc == TREXIO_END);
-  assert(chunk_read == eof_read_size_check);
-  assert(det_list_read[2*int_num*size_r-1] == 0);
-  assert(det_list_read[2*int_num*offset_data_read] == 2 * int_num * (int64_t) (offset_file_read-offset));
-
-  chunk_read = read_size_check;
-  rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
-  /*
-  printf("%s\n", trexio_string_of_error(rc));
-  for (int i=0; i<size_r; i++) {
-    printf("%lf\n", det_coef_read[i]);
-  }
-  */
-  assert(rc == TREXIO_END);
-  assert(chunk_read == eof_read_size_check);
-
-  check_diff= det_coef_read[size_r-1] - 0.;
-  //printf("%lf %lf\n", check_diff, det_coef_read[size_r-1]);
-  assert(check_diff*check_diff < 1e-14);
-
-  // check the value of determinant_num
-  int32_t det_num = 0;
-  int32_t size_check = SIZE;
-  if (offset != 0L) size_check += offset;
-
-  rc = trexio_read_determinant_num(file, &det_num);
-  assert(rc == TREXIO_SUCCESS);
-  assert(det_num == size_check);
-
-  // check conversion of determinants into orbital lists
-  int64_t  size_list = TREXIO_NORB_PER_INT * int_num;
-  int32_t* orb_list_up = (int32_t*) calloc(size_list, sizeof(int32_t));
-  int32_t* orb_list_dn = (int32_t*) calloc(size_list, sizeof(int32_t));
-  int32_t  occ_num_up, occ_num_dn;
-
-  rc = trexio_to_orbital_list_up_dn (int_num, &det_list_read[2*int_num*5], orb_list_up, orb_list_dn, &occ_num_up, &occ_num_dn);
-  assert (rc == TREXIO_SUCCESS);
-  assert (occ_num_up == 14);
-  assert (occ_num_dn == 17);
-  /* // DEBUG printing
-  printf("occ_num_up : %d ; occ_num_dn : %d \n", occ_num_up, occ_num_dn);
-  for (int i=0; i<occ_num_up; i++) {
-     printf("%d ", orb_list_up[i]);
-  }
-  printf("| ");
-  for (int i=0; i<occ_num_dn; i++) {
-     printf("%d ", orb_list_dn[i]);
-  }
-  printf("\n");
-  */
-
-  // check conversion of one orbital list into the bitfield determinant representation
-  int64_t* det_list_check = (int64_t*) calloc(int_num, sizeof(int64_t));
-
-  rc = trexio_to_bitfield_list (orb_list_up, occ_num_up, det_list_check, int_num);
-  assert (rc == TREXIO_SUCCESS);
-  for (int i=0; i<int_num; i++) {
-    assert (det_list_check[i] == det_list_read[2*int_num*5+i]);
-  }
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // free the memory
-  free(det_list_read);
-  free(det_coef_read);
-  free(det_list_check);
-  free(orb_list_up);
-  free(orb_list_dn);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(){
-
-/*============== Test launcher ================*/
-
-  int rc;
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  // check the first write attempt (SIZE elements written in N_CHUNKS chunks)
-  test_write_determinant (TREXIO_FILE, TEST_BACKEND, 0);
-  test_has_determinant   (TREXIO_FILE, TEST_BACKEND);
-  test_read_determinant  (TREXIO_FILE, TEST_BACKEND, 0);
-
-  // check the second write attempt (SIZE elements written in N_CHUNKS chunks)
-  test_write_determinant (TREXIO_FILE, TEST_BACKEND, SIZE);
-  test_read_determinant  (TREXIO_FILE, TEST_BACKEND, SIZE);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_determinant_text.c b/tests/io_determinant_text.c
index b3e6e92f..9ba991b1 100644
--- a/tests/io_determinant_text.c
+++ b/tests/io_determinant_text.c
@@ -1,326 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_determinant"
+#include "test_macros.h"
+#include "io_determinant.c"
 
-#define TEST_BACKEND  TREXIO_TEXT
-#define TREXIO_FILE   "test_determinant.dir"
-#define RM_COMMAND    "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-#define SIZE          100
-#define N_CHUNKS      5
-#define STATE_TEST    2
-#define MO_NUM        150
-
-static int test_write_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
-
-/* Try to write an array of sparse data into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // parameters to be written
-  int64_t* det_list;
-  double*  det_coef;
-
-  int mo_num = MO_NUM;
-
-  // write mo_num which will be used to determine the optimal size of int indices
-  if (trexio_has_mo_num(file) == TREXIO_HAS_NOT) {
-    rc = trexio_write_mo_num(file, mo_num);
-    assert(rc == TREXIO_SUCCESS);
-  }
-
-  // get the number of int64 bit fields per determinant
-  int int_num;
-  rc = trexio_get_int64_num(file, &int_num);
-  assert(rc == TREXIO_SUCCESS);
-  assert(int_num == (MO_NUM-1)/64 + 1);
-
-  // allocate memory and fill with values to be written
-  det_list = (int64_t*) calloc(2 * int_num * SIZE, sizeof(int64_t));
-  det_coef = (double*) calloc(SIZE, sizeof(double));
-
-  for(int i=0; i<SIZE; i++){
-    det_list[6*i]   = 6*i;
-    det_list[6*i+1] = 6*i+1;
-    det_list[6*i+2] = 6*i+2;
-    det_list[6*i+3] = 6*i+3;
-    det_list[6*i+4] = 6*i+4;
-    det_list[6*i+5] = 6*i+5;
-    det_coef[i]     = 3.14 + (double) i;
-  }
-
-  // write dataset chunks of sparse data in the file (including FAKE statements)
-  uint64_t chunk_size = (uint64_t) SIZE/N_CHUNKS;
-  uint64_t offset_f = 0UL;
-  uint64_t offset_d = 0UL;
-  if (offset != 0L) offset_f += offset;
-
-  // write the state_id of a given file: 0 is ground state
-  if (trexio_has_state_id(file) == TREXIO_HAS_NOT) {
-    rc = trexio_write_state_id(file, STATE_TEST);
-    assert(rc == TREXIO_SUCCESS);
-  }
-
-  // write n_chunks times using write_sparse
-  for(int i=0; i<N_CHUNKS; ++i){
-
-    rc = trexio_write_determinant_list(file, offset_f, chunk_size, &det_list[2*int_num*offset_d]);
-    assert(rc == TREXIO_SUCCESS);
-
-    rc = trexio_write_determinant_coefficient(file, offset_f, chunk_size, &det_coef[offset_d]);
-    assert(rc == TREXIO_SUCCESS);
-
-    offset_d += chunk_size;
-    offset_f += chunk_size;
-  }
-
-  // manually check the consistency of the determinant_num and coefficient_size after writing
-  int64_t coeff_size = 0L;
-  int64_t determinant_num = 0L;
-
-  rc = trexio_read_determinant_num_64(file, &determinant_num);
-  assert(rc == TREXIO_SUCCESS);
-
-  rc = trexio_read_determinant_coefficient_size(file, &coeff_size);
-  assert(rc == TREXIO_SUCCESS);
-  assert(determinant_num == coeff_size);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // free the allocated memeory
-  free(det_list);
-  free(det_coef);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_has_determinant(const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // now check that previously written determinant_list exists
-  rc = trexio_has_determinant_list(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  rc = trexio_has_state_id(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // now check that previously written determinant_coefficient exists
-  rc = trexio_has_determinant_coefficient(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_read_determinant (const char* file_name, const back_end_t backend, const int64_t offset) {
-
-/* Try to read one chunk of dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // compute how many integer bit fields is needed per determinant (for a given spin)
-  int64_t mo_num;
-  rc = trexio_read_mo_num_64(file, &mo_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (mo_num == MO_NUM);
-
-  int int_num;
-  rc = trexio_get_int64_num(file, &int_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (int_num == (MO_NUM - 1)/64 + 1);
-
-  // define arrays to read into
-  int64_t* det_list_read;
-  double*  det_coef_read;
-  double check_diff;
-  uint64_t size_r = 40L;
-
-  det_list_read = (int64_t*) calloc(2*int_num*size_r,sizeof(int64_t));
-  det_coef_read = (double*)  calloc(size_r,sizeof(double));
-
-  // specify the read parameters, here:
-  // 1 chunk of 10 elements using offset of 40 (i.e. lines No. 40--59) into elements of the array starting from 5
-  int64_t chunk_read = 10L;
-  int64_t offset_file_read = 40L;
-  int offset_data_read = 5;
-  int64_t read_size_check;
-  read_size_check = chunk_read;
-
-  if (offset != 0L) offset_file_read += offset;
-
-  // read one chunk using the aforementioned parameters
-  rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
-  assert(rc == TREXIO_SUCCESS);
-  assert(chunk_read == read_size_check);
-  assert(det_list_read[0] == 0);
-  assert(det_list_read[2*int_num*offset_data_read] == 2 * int_num * (int64_t) (offset_file_read-offset));
-
-  rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
-  assert(rc == TREXIO_SUCCESS);
-  assert(chunk_read == read_size_check);
-
-  check_diff = det_coef_read[0] - 0.;
-  assert(check_diff*check_diff < 1e-14);
-
-  check_diff = det_coef_read[offset_data_read] - (3.14 + (double) (offset_file_read-offset));
-  //printf("%lf %lf\n", check_diff, det_coef_read[offset_data_read]);
-  assert(check_diff*check_diff < 1e-14);
-
-  int32_t state_id = 666;
-  rc = trexio_read_state_id(file, &state_id);
-  assert(rc == TREXIO_SUCCESS);
-  assert(state_id == STATE_TEST);
-
-  // now attempt to read so that one encounters end of file during reading (i.e. offset_file_read + chunk_read > size_max)
-  offset_file_read = 97L;
-  offset_data_read = 1;
-  int64_t eof_read_size_check = SIZE - offset_file_read; // if offset_file_read=97 => only 3 integrals will be read out of total of 100
-
-  if (offset != 0L) offset_file_read += offset;
-
-  chunk_read = read_size_check;
-  // read one chunk that will reach EOF and return TREXIO_END code
-  rc = trexio_read_determinant_list(file, offset_file_read, &chunk_read, &det_list_read[2*int_num*offset_data_read]);
-  /*
-  printf("%s\n", trexio_string_of_error(rc));
-  for (int i=0; i<size_r; i++) {
-    printf("%lld %lld\n", det_list_read[6*i], det_list_read[6*i+5]);
-  }
-  */
-  assert(rc == TREXIO_END);
-  assert(chunk_read == eof_read_size_check);
-  assert(det_list_read[2*int_num*size_r-1] == 0);
-  assert(det_list_read[2*int_num*offset_data_read] == 2 * int_num * (int64_t) (offset_file_read-offset));
-
-  chunk_read = read_size_check;
-  rc = trexio_read_determinant_coefficient(file, offset_file_read, &chunk_read, &det_coef_read[offset_data_read]);
-  /*
-  printf("%s\n", trexio_string_of_error(rc));
-  for (int i=0; i<size_r; i++) {
-    printf("%lf\n", det_coef_read[i]);
-  }
-  */
-  assert(rc == TREXIO_END);
-  assert(chunk_read == eof_read_size_check);
-
-  check_diff= det_coef_read[size_r-1] - 0.;
-  //printf("%lf %lf\n", check_diff, det_coef_read[size_r-1]);
-  assert(check_diff*check_diff < 1e-14);
-
-  // check the value of determinant_num
-  int32_t det_num = 0;
-  int32_t size_check = SIZE;
-  if (offset != 0L) size_check += offset;
-
-  rc = trexio_read_determinant_num(file, &det_num);
-  assert(rc == TREXIO_SUCCESS);
-  assert(det_num == size_check);
-
-  // check conversion of determinants into orbital lists
-  int64_t  size_list = TREXIO_NORB_PER_INT * int_num;
-  int32_t* orb_list_up = (int32_t*) calloc(size_list, sizeof(int32_t));
-  int32_t* orb_list_dn = (int32_t*) calloc(size_list, sizeof(int32_t));
-  int32_t  occ_num_up, occ_num_dn;
-
-  rc = trexio_to_orbital_list_up_dn (int_num, &det_list_read[2*int_num*5], orb_list_up, orb_list_dn, &occ_num_up, &occ_num_dn);
-  assert (rc == TREXIO_SUCCESS);
-  assert (occ_num_up == 14);
-  assert (occ_num_dn == 17);
-  /* // DEBUG printing
-  printf("occ_num_up : %d ; occ_num_dn : %d \n", occ_num_up, occ_num_dn);
-  for (int i=0; i<occ_num_up; i++) {
-     printf("%d ", orb_list_up[i]);
-  }
-  printf("| ");
-  for (int i=0; i<occ_num_dn; i++) {
-     printf("%d ", orb_list_dn[i]);
-  }
-  printf("\n");
-  */
-
-  // check conversion of one orbital list into the bitfield determinant representation
-  int64_t* det_list_check = (int64_t*) calloc(int_num, sizeof(int64_t));
-
-  rc = trexio_to_bitfield_list (orb_list_up, occ_num_up, det_list_check, int_num);
-  assert (rc == TREXIO_SUCCESS);
-  for (int i=0; i<int_num; i++) {
-    assert (det_list_check[i] == det_list_read[2*int_num*5+i]);
-  }
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // free the memory
-  free(det_list_read);
-  free(det_coef_read);
-  free(det_list_check);
-  free(orb_list_up);
-  free(orb_list_dn);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(){
-
-/*============== Test launcher ================*/
-
-  int rc;
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  // check the first write attempt (SIZE elements written in N_CHUNKS chunks)
-  test_write_determinant (TREXIO_FILE, TEST_BACKEND, 0);
-  test_has_determinant   (TREXIO_FILE, TEST_BACKEND);
-  test_read_determinant  (TREXIO_FILE, TEST_BACKEND, 0);
-
-  // check the second write attempt (SIZE elements written in N_CHUNKS chunks)
-  test_write_determinant (TREXIO_FILE, TEST_BACKEND, SIZE);
-  test_read_determinant  (TREXIO_FILE, TEST_BACKEND, SIZE);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_dset_float.c b/tests/io_dset_float.c
new file mode 100644
index 00000000..693f1397
--- /dev/null
+++ b/tests/io_dset_float.c
@@ -0,0 +1,142 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int test_write_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to write a dataset with numerical (floating point) values into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 12;
+  double coord[36] = {
+  0.00000000 ,  1.39250319 ,  0.00000000 ,
+ -1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -1.20594314 , -0.69625160 ,  0.00000000 ,
+  0.00000000 , -1.39250319 ,  0.00000000 ,
+  1.20594314 , -0.69625160 ,  0.00000000 ,
+  1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -2.14171677 ,  1.23652075 ,  0.00000000 ,
+ -2.14171677 , -1.23652075 ,  0.00000000 ,
+  0.00000000 , -2.47304151 ,  0.00000000 ,
+  2.14171677 , -1.23652075 ,  0.00000000 ,
+  2.14171677 ,  1.23652075 ,  0.00000000 ,
+  0.00000000 ,  2.47304151 ,  0.00000000 ,
+  };
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // write numerical attribute in an empty file
+  rc = trexio_write_nucleus_num(file, num);
+  assert (rc == TREXIO_SUCCESS);
+
+  // write numerical dataset in a file
+  rc = trexio_write_nucleus_coord(file, coord);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_has_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to check the existence of a dataset in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // check that the previously written dataset exists
+  rc = trexio_has_nucleus_coord(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // check that another dataset does not exist
+  rc = trexio_has_mo_coefficient(file);
+  assert (rc == TREXIO_HAS_NOT);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_read_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to read a dataset with numerical (floating point) values from the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be read
+  int num;
+  double* coord;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // read numerical attribute from the file
+  rc = trexio_read_nucleus_num(file, &num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (num == 12);
+
+  // read numerical (floating point) dataset from the file
+  coord = (double*) calloc(3*num, sizeof(double));
+  rc = trexio_read_nucleus_coord(file, coord);
+  assert (rc == TREXIO_SUCCESS);
+
+  double x = coord[30] - 2.14171677;
+  assert( x*x < 1.e-14 );
+  free(coord);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write_dset (TREXIO_FILE, TEST_BACKEND);
+  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
+  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
diff --git a/tests/io_dset_float_hdf5.c b/tests/io_dset_float_hdf5.c
index 90174cd3..84eb58ab 100644
--- a/tests/io_dset_float_hdf5.c
+++ b/tests/io_dset_float_hdf5.c
@@ -1,148 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_dset_f.h5"
-#define RM_COMMAND 	"rm -rf " TREXIO_FILE
-
-static int test_write_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dataset with numerical (floating point) values into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  double coord[36] = {
-  0.00000000 ,  1.39250319 ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000 ,
-  1.20594314 ,  0.69625160 ,  0.00000000 ,
- -2.14171677 ,  1.23652075 ,  0.00000000 ,
- -2.14171677 , -1.23652075 ,  0.00000000 ,
-  0.00000000 , -2.47304151 ,  0.00000000 ,
-  2.14171677 , -1.23652075 ,  0.00000000 ,
-  2.14171677 ,  1.23652075 ,  0.00000000 ,
-  0.00000000 ,  2.47304151 ,  0.00000000 ,
-  };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-  
-  // write numerical dataset in a file
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written dataset exists
-  rc = trexio_has_nucleus_coord(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that another dataset does not exist
-  rc = trexio_has_mo_coefficient(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dataset with numerical (floating point) values from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num;
-  double* coord;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_nucleus_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  // read numerical (floating point) dataset from the file
-  coord = (double*) calloc(3*num, sizeof(double));
-  rc = trexio_read_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  double x = coord[30] - 2.14171677;
-  assert( x*x < 1.e-14 );
-  free(coord);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_dset (TREXIO_FILE, TEST_BACKEND);
-  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
-
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_dset_float"
+#include "test_macros.h"
+#include "io_dset_float.c"
 
diff --git a/tests/io_dset_float_text.c b/tests/io_dset_float_text.c
index 3d311855..69392e87 100644
--- a/tests/io_dset_float_text.c
+++ b/tests/io_dset_float_text.c
@@ -1,146 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_dset_float"
+#include "test_macros.h"
+#include "io_dset_float.c"
 
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_dset_f.dir"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dataset with numerical (floating point) values into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  double coord[36] = {
-  0.00000000 ,  1.39250319 ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000 ,
-  1.20594314 ,  0.69625160 ,  0.00000000 ,
- -2.14171677 ,  1.23652075 ,  0.00000000 ,
- -2.14171677 , -1.23652075 ,  0.00000000 ,
-  0.00000000 , -2.47304151 ,  0.00000000 ,
-  2.14171677 , -1.23652075 ,  0.00000000 ,
-  2.14171677 ,  1.23652075 ,  0.00000000 ,
-  0.00000000 ,  2.47304151 ,  0.00000000 ,
-  };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write numerical dataset in a file
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written dataset exists
-  rc = trexio_has_nucleus_coord(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that another dataset does not exist
-  rc = trexio_has_mo_coefficient(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dataset with numerical (floating point) values from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num;
-  double* coord;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_nucleus_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  // read numerical (floating point) dataset from the file
-  coord = (double*) calloc(3*num, sizeof(double));
-  rc = trexio_read_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  double x = coord[30] - 2.14171677;
-  assert( x*x < 1.e-14 );
-  free(coord);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_dset (TREXIO_FILE, TEST_BACKEND);
-  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_dset_int.c b/tests/io_dset_int.c
new file mode 100644
index 00000000..137da06c
--- /dev/null
+++ b/tests/io_dset_int.c
@@ -0,0 +1,147 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int test_write_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to write a dataset with numerical (int) values into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 12;
+  int nucl_index[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
+  int state_id = 2;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // write numerical attribute in an empty file
+  rc = trexio_write_basis_shell_num(file, num);
+  assert (rc == TREXIO_SUCCESS);
+
+  // write numerical (integer) dataset in a file
+  rc = trexio_write_basis_nucleus_index(file, nucl_index);
+  assert (rc == TREXIO_SUCCESS);
+
+  // write index attribute in a file
+  rc = trexio_write_state_id(file, state_id);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_has_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to check the existence of a dataset in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // check that the group exists
+  rc = trexio_has_basis(file);
+  assert(rc==TREXIO_SUCCESS);
+
+  // check that the group does not exist
+  rc = trexio_has_mo(file);
+  assert(rc==TREXIO_HAS_NOT);
+
+  // check that the previously written dataset exists
+  rc = trexio_has_basis_nucleus_index(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // check that another dataset does not exist
+  rc = trexio_has_mo_coefficient(file);
+  assert (rc == TREXIO_HAS_NOT);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_read_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to read a dataset with numericali (int) values from the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be read
+  int num = 0;
+  int* nucl_index = NULL;
+  int state_id = 0;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // read numerical attribute from the file
+  rc = trexio_read_basis_shell_num(file, &num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (num == 12);
+
+  // read index attribute from the file
+  rc = trexio_read_state_id(file, &state_id);
+  assert (rc == TREXIO_SUCCESS);
+  assert (state_id == 2);
+
+  // read numerical dataset from the file
+  nucl_index = (int*) calloc(num, sizeof(int));
+  rc = trexio_read_basis_nucleus_index(file, nucl_index);
+  assert (rc == TREXIO_SUCCESS);
+  assert (nucl_index[num-1] == num-1);
+
+  free(nucl_index);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write_dset (TREXIO_FILE, TEST_BACKEND);
+  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
+  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
diff --git a/tests/io_dset_int_hdf5.c b/tests/io_dset_int_hdf5.c
index d307cba1..3237d3e4 100644
--- a/tests/io_dset_int_hdf5.c
+++ b/tests/io_dset_int_hdf5.c
@@ -1,151 +1,4 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_dset_i.h5"
-#define RM_COMMAND 	"rm -rf " TREXIO_FILE
-
-static int test_write_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dataset with numerical (int) values into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  int nucl_index[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-  int state_id = 2;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_basis_shell_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write numerical (integer) dataset in a file
-  rc = trexio_write_basis_nucleus_index(file, nucl_index);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write index attribute in a file
-  rc = trexio_write_state_id(file, state_id);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the group exists
-  rc = trexio_has_basis(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // check that the group does not exist
-  rc = trexio_has_mo(file);
-  assert(rc==TREXIO_HAS_NOT);
-
-  // check that the previously written dataset exists
-  rc = trexio_has_basis_nucleus_index(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that another dataset does not exist
-  rc = trexio_has_mo_coefficient(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dataset with numericali (int) values from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num = 0;
-  int* nucl_index = NULL;
-  int state_id = 0;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_basis_shell_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  // read index attribute from the file
-  rc = trexio_read_state_id(file, &state_id);
-  assert (rc == TREXIO_SUCCESS);
-  assert (state_id == 2);
-
-  // read numerical dataset from the file
-  nucl_index = (int*) calloc(num, sizeof(int));
-  rc = trexio_read_basis_nucleus_index(file, nucl_index);
-  assert (rc == TREXIO_SUCCESS);
-  assert (nucl_index[num-1] == num-1);
-
-  free(nucl_index);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_dset (TREXIO_FILE, TEST_BACKEND);
-  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_dset_int"
+#include "test_macros.h"
+#include "io_dset_int.c"
diff --git a/tests/io_dset_int_text.c b/tests/io_dset_int_text.c
index 09c536b1..0f7bbee2 100644
--- a/tests/io_dset_int_text.c
+++ b/tests/io_dset_int_text.c
@@ -1,151 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_dset_int"
+#include "test_macros.h"
+#include "io_dset_int.c"
 
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_dset_i.dir"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dataset with numerical (int) values into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  int nucl_index[12] = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11};
-  int state_id = 2;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_basis_shell_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write numerical (integer) dataset in a file
-  rc = trexio_write_basis_nucleus_index(file, nucl_index);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write index attribute in a file
-  rc = trexio_write_state_id(file, state_id);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the group exists
-  rc = trexio_has_basis(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // check that the group does not exist
-  rc = trexio_has_mo(file);
-  assert(rc==TREXIO_HAS_NOT);
-
-  // check that the previously written dataset exists
-  rc = trexio_has_basis_nucleus_index(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that another dataset does not exist
-  rc = trexio_has_mo_coefficient(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dataset with numericali (int) values from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num = 0;
-  int* nucl_index = NULL;
-  int state_id = 0;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_basis_shell_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  // read index attribute from the file
-  rc = trexio_read_state_id(file, &state_id);
-  assert (rc == TREXIO_SUCCESS);
-  assert (state_id == 2);
-
-  // read numerical dataset from the file
-  nucl_index = (int*) calloc(num, sizeof(int));
-  rc = trexio_read_basis_nucleus_index(file, nucl_index);
-  assert (rc == TREXIO_SUCCESS);
-  assert (nucl_index[num-1] == num-1);
-
-  free(nucl_index);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_dset (TREXIO_FILE, TEST_BACKEND);
-  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_dset_sparse.c b/tests/io_dset_sparse.c
new file mode 100644
index 00000000..298158e5
--- /dev/null
+++ b/tests/io_dset_sparse.c
@@ -0,0 +1,268 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#define N_CHUNKS      4
+
+static int test_write_dset_sparse (const char* file_name, const back_end_t backend, const int64_t offset, const int64_t mo_num) {
+
+/* Try to write an array of sparse data into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // parameters to be written
+  int32_t* index;
+  double* value;
+  int64_t size = mo_num/2;
+
+  index = calloc(4L*size, sizeof(int32_t));
+  value = calloc(size, sizeof(double));
+
+  for(int i=0; i<size; i++){
+    index[4*i]   = i;
+    index[4*i+1] = i+1;
+    index[4*i+2] = i+2;
+    index[4*i+3] = i+3;
+    value[i]     = 3.14 + (double) i;
+  }
+
+  // write mo_num which will be used to determine the optimal size of int indices
+  if (trexio_has_mo_num(file) == TREXIO_HAS_NOT) {
+    rc = trexio_write_mo_num(file, mo_num);
+    assert(rc == TREXIO_SUCCESS);
+  }
+
+  // write dataset chunks of sparse data in the file (including FAKE statements)
+  uint64_t chunk_size = (uint64_t) size/N_CHUNKS;
+  chunk_size = chunk_size > 0 ? chunk_size : (uint64_t) size;
+  int n_chunks = size/chunk_size;
+  printf("chunk_size = %ld\n", chunk_size);
+  printf("n_chunks   = %d\n", n_chunks);
+
+  uint64_t offset_f = 0UL + offset;
+  uint64_t offset_d = 0UL;
+
+  // write n_chunks times using write_sparse
+  while(offset_d < size) {
+    if (offset_d+chunk_size > size) chunk_size = size-offset_d;
+  printf("chunk_size = %ld\n", chunk_size);
+    if (chunk_size == 0L) break;
+    rc = trexio_write_mo_2e_int_eri(file, offset_f, chunk_size, &index[4*offset_d], &value[offset_d]);
+    printf("%5d: %s\n", __LINE__, trexio_string_of_error(rc));
+    assert(rc == TREXIO_SUCCESS);
+    offset_d += chunk_size;
+    offset_f += chunk_size;
+  }
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // free the allocated memeory
+  free(index);
+  free(value);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+static int test_has_dset_sparse (const char* file_name, const back_end_t backend) {
+
+/* Try to check the existence of a dataset of sparse data in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // check that the group exists
+  rc = trexio_has_mo_2e_int(file);
+  assert(rc==TREXIO_SUCCESS);
+
+  // check that the group does not exist
+  rc = trexio_has_rdm(file);
+  assert(rc==TREXIO_HAS_NOT);
+
+  // first check that mo_2e_int_eri_lr (we only write non-lr component in this unit test)
+  rc = trexio_has_mo_2e_int_eri_lr(file);
+  assert(rc==TREXIO_HAS_NOT);
+
+  // check that previous call to has_sparse did not create a file/dset
+  rc = trexio_has_mo_2e_int_eri_lr(file);
+  assert(rc==TREXIO_HAS_NOT);
+
+  // now check that previously written mo_2e_int_eri exists
+  rc = trexio_has_mo_2e_int_eri(file);
+  assert(rc==TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+static int test_read_dset_sparse (const char* file_name, const back_end_t backend, const int64_t offset) {
+
+/* Try to read one chunk of dataset of sparse data in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  int32_t mo_num = 0;
+  rc = trexio_read_mo_num(file, &mo_num);
+  assert(rc == TREXIO_SUCCESS);
+  printf("%5d: mo_num = %d\n", __LINE__, mo_num);
+  const int64_t size = mo_num/2;
+
+ // define arrays to read into
+  int32_t* index_read;
+  double* value_read;
+  uint64_t size_r = mo_num;
+
+  index_read = (int32_t*) calloc(4L*size_r,sizeof(int32_t));
+  value_read = (double*) calloc(size_r,sizeof(double));
+
+  // specify the read parameters, here:
+  // 1 chunk of 10 elements using offset of 40 (i.e. lines No. 40--59) into elements of the array starting from 5
+  int64_t chunk_read = size/3;
+  chunk_read = chunk_read < 2 ? 2 : chunk_read;
+  int64_t offset_file_read = 1;
+  int64_t read_size_check;
+  read_size_check = chunk_read;
+
+  if (offset != 0L) offset_file_read += offset;
+
+  // read one chunk using the aforementioned parameters
+  rc = trexio_read_mo_2e_int_eri(file, offset_file_read, &chunk_read, &index_read[0], &value_read[0]);
+  printf("%5d: %s\n", __LINE__, trexio_string_of_error(rc));
+/*
+  for (int i=0 ; i<chunk_read ; ++i) {
+    printf("%d %d | %ld %ld %ld\n", i, index_read[i], offset, offset_file_read, chunk_read);
+  }
+*/
+  //assert(rc == TREXIO_SUCCESS);
+  assert(chunk_read == read_size_check);
+  assert(index_read[0] == offset_file_read-offset);
+
+
+  // now attempt to read so that one encounters end of file during reading (i.e. offset_file_read + chunk_read > size_max)
+  int64_t size_max;
+  rc = trexio_read_mo_2e_int_eri_size(file, &size_max);
+  assert(rc == TREXIO_SUCCESS);
+  offset_file_read = size_max-chunk_read+1;
+  int64_t eof_read_size_check = size_max - offset_file_read; // if offset_file_read=97 => only 3 integrals will be read out of total of 100
+
+
+  // read one chunk that will reach EOF and return TREXIO_END code
+  rc = trexio_read_mo_2e_int_eri(file, offset_file_read, &chunk_read, &index_read[0], &value_read[0]);
+  printf("%5d: %s\n", __LINE__, trexio_string_of_error(rc));
+  assert(rc == TREXIO_END);
+  printf("%d %d  x\n", (int32_t) index_read[0], (int32_t) (4L*offset_file_read));
+  printf("%ld  %ld\n", chunk_read, eof_read_size_check);
+  assert(chunk_read == eof_read_size_check);
+  printf("%d %d\n", index_read[0] , (int32_t) (offset_file_read - offset));
+  assert(index_read[0] == (int32_t) offset_file_read - offset);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // free the memory
+  free(index_read);
+  free(value_read);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+static int test_read_dset_sparse_size (const char* file_name, const back_end_t backend, const int64_t size_check) {
+
+/* Try to read a size of the dataset of sparse data in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // define the variable to read into
+  int64_t size_written;
+
+  // read one chunk using the aforementioned parameters
+  rc = trexio_read_mo_2e_int_eri_size(file, &size_written);
+  assert(rc == TREXIO_SUCCESS);
+  printf("%5d: %ld %ld\n", __LINE__, size_written, size_check);
+  assert(size_written == size_check);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+int main(){
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  int32_t mo_num[8] = {6,12,30,62,252,510,1020,9000};
+
+  for (int i=0 ; i<8 ; ++i) {
+
+    printf("%5d: mo_num = %d\n", __LINE__, mo_num[i]);
+    const int64_t size = mo_num[i]/2;
+    // check the first write attempt (SIZE elements written in N_CHUNKS chunks)
+    test_write_dset_sparse    (TREXIO_FILE, TEST_BACKEND, 0, mo_num[i]);
+    test_has_dset_sparse      (TREXIO_FILE, TEST_BACKEND);
+    test_read_dset_sparse     (TREXIO_FILE, TEST_BACKEND, 0);
+    test_read_dset_sparse_size(TREXIO_FILE, TEST_BACKEND, size);
+
+    // check the second write attempt (SIZE elements written in N_CHUNKS chunks)
+    test_write_dset_sparse    (TREXIO_FILE, TEST_BACKEND, size, mo_num[i]);
+    test_read_dset_sparse     (TREXIO_FILE, TEST_BACKEND, size);
+    test_read_dset_sparse_size(TREXIO_FILE, TEST_BACKEND, 2*size);
+
+    rc = system(RM_COMMAND);
+    assert (rc == 0);
+
+  }
+
+  return 0;
+}
diff --git a/tests/io_dset_sparse_hdf5.c b/tests/io_dset_sparse_hdf5.c
index 7e57ec68..ec691bc7 100644
--- a/tests/io_dset_sparse_hdf5.c
+++ b/tests/io_dset_sparse_hdf5.c
@@ -1,238 +1,4 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#define TEST_BACKEND  TREXIO_HDF5
-#define TREXIO_FILE   "test_dset_sparse.h5"
-#define RM_COMMAND    "rm -f -- " TREXIO_FILE
-#define SIZE          100
-#define N_CHUNKS      5
-
-static int test_write_dset_sparse (const char* file_name, const back_end_t backend, const int64_t offset) {
-
-/* Try to write an array of sparse data into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // parameters to be written
-  int32_t* index;
-  double* value;
-
-  index = calloc(4L*SIZE, sizeof(int32_t));
-  value = calloc(SIZE, sizeof(double));
-
-  for(int i=0; i<SIZE; i++){
-    index[4*i]   = 4*i;
-    index[4*i+1] = 4*i+1;
-    index[4*i+2] = 4*i+2;
-    index[4*i+3] = 4*i+3;
-    value[i]     = 3.14 + (double) i;
-  }
-
-  // write mo_num which will be used to determine the optimal size of int indices
-  if (trexio_has_mo_num(file) == TREXIO_HAS_NOT) {
-    rc = trexio_write_mo_num(file, 1000);
-    assert(rc == TREXIO_SUCCESS);
-  }
-
-  // write dataset chunks of sparse data in the file (including FAKE statements)
-  uint64_t chunk_size = (uint64_t) SIZE/N_CHUNKS;
-  uint64_t offset_f = 0UL;
-  uint64_t offset_d = 0UL;
-  if (offset != 0L) offset_f += offset;
-
-  // write n_chunks times using write_sparse
-  for(int i=0; i<N_CHUNKS; ++i){
-    rc = trexio_write_mo_2e_int_eri(file, offset_f, chunk_size, &index[4*offset_d], &value[offset_d]);
-    assert(rc == TREXIO_SUCCESS);
-    offset_d += chunk_size;
-    offset_f += chunk_size;
-  }
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // free the allocated memeory
-  free(index);
-  free(value);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_has_dset_sparse (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that the group exists
-  rc = trexio_has_mo_2e_int(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // check that the group does not exist
-  rc = trexio_has_rdm(file);
-  assert(rc==TREXIO_HAS_NOT);
-
-  // first check that mo_2e_int_eri_lr (we only write non-lr component in this unit test)
-  rc = trexio_has_mo_2e_int_eri_lr(file);
-  assert(rc==TREXIO_HAS_NOT);
-
-  // check that previous call to has_sparse did not create a file/dset
-  rc = trexio_has_mo_2e_int_eri_lr(file);
-  assert(rc==TREXIO_HAS_NOT);
-
-  // now check that previously written mo_2e_int_eri exists
-  rc = trexio_has_mo_2e_int_eri(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_read_dset_sparse (const char* file_name, const back_end_t backend, const int64_t offset) {
-
-/* Try to read one chunk of dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
- // define arrays to read into
-  int32_t* index_read;
-  double* value_read;
-  uint64_t size_r = 40L;
-
-  index_read = (int32_t*) calloc(4L*size_r,sizeof(int32_t));
-  value_read = (double*) calloc(size_r,sizeof(double));
-
-  // specify the read parameters, here:
-  // 1 chunk of 10 elements using offset of 40 (i.e. lines No. 40--59) into elements of the array starting from 5
-  int64_t chunk_read = 10L;
-  int64_t offset_file_read = 40L;
-  int offset_data_read = 5;
-  int64_t read_size_check;
-  read_size_check = chunk_read;
-
-  if (offset != 0L) offset_file_read += offset;
-
-  // read one chunk using the aforementioned parameters
-  rc = trexio_read_mo_2e_int_eri(file, offset_file_read, &chunk_read, &index_read[4*offset_data_read], &value_read[offset_data_read]);
-  assert(rc == TREXIO_SUCCESS);
-  assert(chunk_read == read_size_check);
-  assert(index_read[0] == 0);
-  assert(index_read[4*offset_data_read] == 4 * (int32_t) (offset_file_read-offset));
-
-  // now attempt to read so that one encounters end of file during reading (i.e. offset_file_read + chunk_read > size_max)
-  offset_file_read = 97L;
-  offset_data_read = 1;
-  int64_t eof_read_size_check = SIZE - offset_file_read; // if offset_file_read=97 => only 3 integrals will be read out of total of 100
-
-  if (offset != 0L) offset_file_read += offset;
-
-  // read one chunk that will reach EOF and return TREXIO_END code
-  rc = trexio_read_mo_2e_int_eri(file, offset_file_read, &chunk_read, &index_read[4*offset_data_read], &value_read[offset_data_read]);
-  assert(rc == TREXIO_END);
-  assert(chunk_read == eof_read_size_check);
-  assert(index_read[4*size_r-1] == 0);
-  assert(index_read[4*offset_data_read] == 4 * (int32_t) (offset_file_read-offset));
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // free the memory
-  free(index_read);
-  free(value_read);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_read_dset_sparse_size (const char* file_name, const back_end_t backend, const int64_t size_check) {
-
-/* Try to read a size of the dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // define the variable to read into
-  int64_t size_written;
-
-  // read one chunk using the aforementioned parameters
-  rc = trexio_read_mo_2e_int_eri_size(file, &size_written);
-  assert(rc == TREXIO_SUCCESS);
-  assert(size_written == size_check);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-int main(){
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  // check the first write attempt (SIZE elements written in N_CHUNKS chunks)
-  test_write_dset_sparse    (TREXIO_FILE, TEST_BACKEND, 0);
-  test_has_dset_sparse      (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset_sparse     (TREXIO_FILE, TEST_BACKEND, 0);
-  test_read_dset_sparse_size(TREXIO_FILE, TEST_BACKEND, SIZE);
-
-  // check the second write attempt (SIZE elements written in N_CHUNKS chunks)
-  test_write_dset_sparse    (TREXIO_FILE, TEST_BACKEND, SIZE);
-  test_read_dset_sparse     (TREXIO_FILE, TEST_BACKEND, SIZE);
-  test_read_dset_sparse_size(TREXIO_FILE, TEST_BACKEND, SIZE*2);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_dset_sparse"
+#include "test_macros.h"
+#include "io_dset_sparse.c"
diff --git a/tests/io_dset_sparse_text.c b/tests/io_dset_sparse_text.c
index caddb9a8..4215f96c 100644
--- a/tests/io_dset_sparse_text.c
+++ b/tests/io_dset_sparse_text.c
@@ -1,238 +1,4 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#define TEST_BACKEND  TREXIO_TEXT
-#define TREXIO_FILE   "test_dset_sparse.dir"
-#define RM_COMMAND    "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-#define SIZE          100
-#define N_CHUNKS      5
-
-static int test_write_dset_sparse (const char* file_name, const back_end_t backend, const int64_t offset) {
-
-/* Try to write an array of sparse data into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // parameters to be written
-  int32_t* index;
-  double* value;
-
-  index = calloc(4L*SIZE, sizeof(int32_t));
-  value = calloc(SIZE, sizeof(double));
-
-  for(int i=0; i<SIZE; i++){
-    index[4*i]   = 4*i;
-    index[4*i+1] = 4*i+1;
-    index[4*i+2] = 4*i+2;
-    index[4*i+3] = 4*i+3;
-    value[i]     = 3.14 + (double) i;
-  }
-
-  // write mo_num which will be used to determine the optimal size of int indices
-  if (trexio_has_mo_num(file) == TREXIO_HAS_NOT) {
-    rc = trexio_write_mo_num(file, 1000);
-    assert(rc == TREXIO_SUCCESS);
-  }
-
-  // write dataset chunks of sparse data in the file (including FAKE statements)
-  uint64_t chunk_size = (uint64_t) SIZE/N_CHUNKS;
-  uint64_t offset_f = 0UL;
-  uint64_t offset_d = 0UL;
-  if (offset != 0L) offset_f += offset;
-
-  // write n_chunks times using write_sparse
-  for(int i=0; i<N_CHUNKS; ++i){
-    rc = trexio_write_mo_2e_int_eri(file, offset_f, chunk_size, &index[4*offset_d], &value[offset_d]);
-    assert(rc == TREXIO_SUCCESS);
-    offset_d += chunk_size;
-    offset_f += chunk_size;
-  }
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // free the allocated memeory
-  free(index);
-  free(value);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_has_dset_sparse (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that the group exists
-  rc = trexio_has_mo_2e_int(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // check that the group does not exist
-  rc = trexio_has_rdm(file);
-  assert(rc==TREXIO_HAS_NOT);
-
-  // first check that mo_2e_int_eri_lr (we only write non-lr component in this unit test)
-  rc = trexio_has_mo_2e_int_eri_lr(file);
-  assert(rc==TREXIO_HAS_NOT);
-
-  // check that previous call to has_sparse did not create a file/dset
-  rc = trexio_has_mo_2e_int_eri_lr(file);
-  assert(rc==TREXIO_HAS_NOT);
-
-  // now check that previously written mo_2e_int_eri exists
-  rc = trexio_has_mo_2e_int_eri(file);
-  assert(rc==TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_read_dset_sparse (const char* file_name, const back_end_t backend, const int64_t offset) {
-
-/* Try to read one chunk of dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
- // define arrays to read into
-  int32_t* index_read;
-  double* value_read;
-  uint64_t size_r = 40L;
-
-  index_read = (int32_t*) calloc(4L*size_r,sizeof(int32_t));
-  value_read = (double*) calloc(size_r,sizeof(double));
-
-  // specify the read parameters, here:
-  // 1 chunk of 10 elements using offset of 40 (i.e. lines No. 40--59) into elements of the array starting from 5
-  int64_t chunk_read = 10L;
-  int64_t offset_file_read = 40L;
-  int offset_data_read = 5;
-  int64_t read_size_check;
-  read_size_check = chunk_read;
-
-  if (offset != 0L) offset_file_read += offset;
-
-  // read one chunk using the aforementioned parameters
-  rc = trexio_read_mo_2e_int_eri(file, offset_file_read, &chunk_read, &index_read[4*offset_data_read], &value_read[offset_data_read]);
-  assert(rc == TREXIO_SUCCESS);
-  assert(chunk_read == read_size_check);
-  assert(index_read[0] == 0);
-  assert(index_read[4*offset_data_read] == 4 * (int32_t) (offset_file_read-offset));
-
-  // now attempt to read so that one encounters end of file during reading (i.e. offset_file_read + chunk_read > size_max)
-  offset_file_read = 97L;
-  offset_data_read = 1;
-  int64_t eof_read_size_check = SIZE - offset_file_read; // if offset_file_read=97 => only 3 integrals will be read out of total of 100
-
-  if (offset != 0L) offset_file_read += offset;
-
-  // read one chunk that will reach EOF and return TREXIO_END code
-  rc = trexio_read_mo_2e_int_eri(file, offset_file_read, &chunk_read, &index_read[4*offset_data_read], &value_read[offset_data_read]);
-  assert(rc == TREXIO_END);
-  assert(chunk_read == eof_read_size_check);
-  assert(index_read[4*size_r-1] == 0);
-  assert(index_read[4*offset_data_read] == 4 * (int32_t) (offset_file_read-offset));
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // free the memory
-  free(index_read);
-  free(value_read);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_read_dset_sparse_size (const char* file_name, const back_end_t backend, const int64_t size_check) {
-
-/* Try to read a size of the dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // define the variable to read into
-  int64_t size_written;
-
-  // read one chunk using the aforementioned parameters
-  rc = trexio_read_mo_2e_int_eri_size(file, &size_written);
-  assert(rc == TREXIO_SUCCESS);
-  assert(size_written == size_check);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-int main(){
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  // check the first write attempt (SIZE elements written in N_CHUNKS chunks)
-  test_write_dset_sparse    (TREXIO_FILE, TEST_BACKEND, 0);
-  test_has_dset_sparse      (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset_sparse     (TREXIO_FILE, TEST_BACKEND, 0);
-  test_read_dset_sparse_size(TREXIO_FILE, TEST_BACKEND, SIZE);
-
-  // check the second write attempt (SIZE elements written in N_CHUNKS chunks)
-  test_write_dset_sparse    (TREXIO_FILE, TEST_BACKEND, SIZE);
-  test_read_dset_sparse     (TREXIO_FILE, TEST_BACKEND, SIZE);
-  test_read_dset_sparse_size(TREXIO_FILE, TEST_BACKEND, SIZE*2);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_dset_sparse"
+#include "test_macros.h"
+#include "io_dset_sparse.c"
diff --git a/tests/io_dset_str.c b/tests/io_dset_str.c
new file mode 100644
index 00000000..90735b57
--- /dev/null
+++ b/tests/io_dset_str.c
@@ -0,0 +1,153 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int test_write_dset_str (const char* file_name, const back_end_t backend) {
+
+/* Try to write an array of strings into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 12;
+  const char* labels[] = {"C"       ,
+                          "Na FAKE" ,
+                          "C"       ,
+                          "C"       ,
+                          "C"       ,
+                          "C"       ,
+                          "H"       ,
+                          "H"       ,
+                          "H"       ,
+                          "H"       ,
+                          "H"       ,
+                          "H FAKE"  };
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // write numerical attribute in an empty file
+  rc = trexio_write_nucleus_num(file, num);
+  assert (rc == TREXIO_SUCCESS);
+  
+  // write dataset of string in the file (including FAKE statements)
+  int max_str_len = 16;
+  rc = trexio_write_nucleus_label(file, labels, max_str_len);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_has_dset_str (const char* file_name, const back_end_t backend) {
+
+/* Try to check the existence of a dataset of strings in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // check that the previously written dataset of strings exists
+  rc = trexio_has_nucleus_label(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // check that the dataset of strings does not exist
+  rc = trexio_has_mo_symmetry(file);
+  assert (rc == TREXIO_HAS_NOT);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_read_dset_str (const char* file_name, const back_end_t backend) {
+
+/* Try to read a dataset with strings from the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be read
+  int num;
+  char** labels;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // read numerical attribute from the file
+  rc = trexio_read_nucleus_num(file, &num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (num == 12);
+
+  // read the arrays of strings truncated to max_str_len=2 symbols
+  int max_str_len = 2;
+
+  labels = (char**) malloc(num*sizeof(char*));
+  for (int i=0; i<num; i++){
+    labels[i] = (char*) malloc((max_str_len+1)*sizeof(char));
+  }
+
+  rc = trexio_read_nucleus_label(file, labels, max_str_len);
+  assert (rc == TREXIO_SUCCESS);
+  assert (strcmp(labels[0], "C")  == 0);
+  assert (strcmp(labels[1], "Na") == 0);
+
+  for (int i=0; i<num; i++){
+    free(labels[i]);
+  }
+  free(labels);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write_dset_str (TREXIO_FILE, TEST_BACKEND);
+  test_has_dset_str   (TREXIO_FILE, TEST_BACKEND);
+  test_read_dset_str  (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
+
+
diff --git a/tests/io_dset_str_hdf5.c b/tests/io_dset_str_hdf5.c
index fed85bc0..bd9bd574 100644
--- a/tests/io_dset_str_hdf5.c
+++ b/tests/io_dset_str_hdf5.c
@@ -1,157 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_dset_s.h5"
-#define RM_COMMAND 	"rm -rf " TREXIO_FILE
-
-static int test_write_dset_str (const char* file_name, const back_end_t backend) {
-
-/* Try to write an array of strings into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  const char* labels[] = {"C"       ,
-                          "Na FAKE" ,
-                          "C"       ,
-                          "C"       ,
-                          "C"       ,
-                          "C"       ,
-                          "H"       ,
-                          "H"       ,
-                          "H"       ,
-                          "H"       ,
-                          "H"       ,
-                          "H FAKE"  };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-  
-  // write dataset of string in the file (including FAKE statements)
-  int max_str_len = 16;
-  rc = trexio_write_nucleus_label(file, labels, max_str_len);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_dset_str (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset of strings in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written dataset of strings exists
-  rc = trexio_has_nucleus_label(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that the dataset of strings does not exist
-  rc = trexio_has_mo_symmetry(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_dset_str (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dataset with strings from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num;
-  char** labels;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_nucleus_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  // read the arrays of strings truncated to max_str_len=2 symbols
-  int max_str_len = 2;
-
-  labels = (char**) malloc(num*sizeof(char*));
-  for (int i=0; i<num; i++){
-    labels[i] = (char*) malloc((max_str_len+1)*sizeof(char));
-  }
-
-  rc = trexio_read_nucleus_label(file, labels, max_str_len);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp(labels[0], "C")  == 0);
-  assert (strcmp(labels[1], "Na") == 0);
-
-  for (int i=0; i<num; i++){
-    free(labels[i]);
-  }
-  free(labels);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_dset_str (TREXIO_FILE, TEST_BACKEND);
-  test_has_dset_str   (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset_str  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
-
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_dset_str"
+#include "test_macros.h"
+#include "io_dset_str.c"
 
diff --git a/tests/io_dset_str_text.c b/tests/io_dset_str_text.c
index e52abc87..f92a1e03 100644
--- a/tests/io_dset_str_text.c
+++ b/tests/io_dset_str_text.c
@@ -1,155 +1,4 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_dset_s.dir"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write_dset_str (const char* file_name, const back_end_t backend) {
-
-/* Try to write an array of strings into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  const char* labels[] = {"C"       ,
-                          "Na FAKE" ,
-                          "C"       ,
-                          "C"       ,
-                          "C"       ,
-                          "C"       ,
-                          "H"       ,
-                          "H"       ,
-                          "H"       ,
-                          "H"       ,
-                          "H"       ,
-                          "H FAKE"  };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  // write dataset of string in the file (including FAKE statements)
-  int max_str_len = 16;
-  rc = trexio_write_nucleus_label(file, labels, max_str_len);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_dset_str (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset of strings in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written dataset of strings exists
-  rc = trexio_has_nucleus_label(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that the dataset of strings does not exist
-  rc = trexio_has_mo_symmetry(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_dset_str (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dataset with strings from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num;
-  char **labels;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_nucleus_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  // read the arrays of strings truncated to max_str_len=2 symbols
-  int max_str_len = 2;
-
-  labels = (char**) malloc(num*sizeof(char*));
-  for (int i=0; i<num; i++){
-    labels[i] = (char*) malloc((max_str_len+1)*sizeof(char));
-  }
-
-  rc = trexio_read_nucleus_label(file, labels, max_str_len);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp(labels[0], "C")  == 0);
-  assert (strcmp(labels[1], "Na") == 0);
-
-  for (int i=0; i<num; i++){
-    free(labels[i]);
-  }
-  free(labels);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_dset_str (TREXIO_FILE, TEST_BACKEND);
-  test_has_dset_str   (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset_str  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_dset_str"
+#include "test_macros.h"
+#include "io_dset_str.c"
diff --git a/tests/io_jastrow.c b/tests/io_jastrow.c
new file mode 100644
index 00000000..96d5b61a
--- /dev/null
+++ b/tests/io_jastrow.c
@@ -0,0 +1,194 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+static int test_write_jastrow (const char* file_name, const back_end_t backend) {
+
+/* Try to write an array of sparse data into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+#define nucleus_num  3
+#define ee_num 2
+#define en_num 3
+#define een_num 6
+
+  rc = trexio_write_nucleus_num(file, nucleus_num);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_jastrow_type(file, "CHAMP", 6);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_jastrow_ee_num(file, ee_num);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_jastrow_en_num(file, en_num);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_jastrow_een_num(file, een_num);
+  assert (rc == TREXIO_SUCCESS);
+
+  double ee [2] = { 0.5, 2. };
+  rc = trexio_write_jastrow_ee(file, ee);
+  assert (rc == TREXIO_SUCCESS);
+
+  double en [3] = { 1., 2., 3. };
+  rc = trexio_write_jastrow_en(file, en);
+  assert (rc == TREXIO_SUCCESS);
+
+  double een [6] = { 11., 12., 13., 14., 15., 16. };
+  rc = trexio_write_jastrow_een(file, een);
+  assert (rc == TREXIO_SUCCESS);
+
+  int en_nucleus [3] = { 0, 1, 2 };
+  rc = trexio_write_jastrow_en_nucleus(file, en_nucleus);
+  assert (rc == TREXIO_SUCCESS);
+
+  int een_nucleus [6] = { 0, 0, 1, 1, 2, 2 };
+  rc = trexio_write_jastrow_een_nucleus(file, een_nucleus);
+  assert (rc == TREXIO_SUCCESS);
+
+  double ee_scaling = 1.0;
+  rc = trexio_write_jastrow_ee_scaling(file, ee_scaling);
+  assert (rc == TREXIO_SUCCESS);
+
+  double en_scaling[3] = { 0.5, 1.0, 0.5 };
+  rc = trexio_write_jastrow_en_scaling(file, en_scaling);
+  assert (rc == TREXIO_SUCCESS);
+
+#undef nucleus_num
+#undef ee_num
+#undef en_num
+#undef een_num
+
+  rc = trexio_close(file);
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+static int test_read_jastrow (const char* file_name, const back_end_t backend) {
+
+/* Try to read one chunk of dataset of sparse data in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  int nucleus_num = 0;
+  rc = trexio_read_nucleus_num(file, &nucleus_num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (nucleus_num == 3);
+
+  char type[16] = "";
+  rc = trexio_read_jastrow_type(file, type, 16);
+  assert (rc == TREXIO_SUCCESS);
+  assert (strcmp("CHAMP",type) == 0);
+
+  int ee_num = 0;
+  rc = trexio_read_jastrow_ee_num(file, &ee_num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (ee_num == 2);
+
+  int en_num = 0;
+  rc = trexio_read_jastrow_en_num(file, &en_num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (en_num == nucleus_num);
+
+  int een_num = 0;
+  rc = trexio_read_jastrow_een_num(file, &een_num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (een_num == 2*nucleus_num);
+
+  double ee [2] = { 0., 0. };
+  rc = trexio_read_jastrow_ee(file, ee);
+  assert (rc == TREXIO_SUCCESS);
+  assert (ee[0] == 0.5);
+  assert (ee[1] == 2.0);
+
+  double en [3] = { 0., 0., 0. };
+  rc = trexio_read_jastrow_en(file, en);
+  assert (rc == TREXIO_SUCCESS);
+  assert (en[0] == 1.0);
+  assert (en[1] == 2.0);
+  assert (en[2] == 3.0);
+
+  double een [6];
+  rc = trexio_read_jastrow_een(file, een);
+  assert (rc == TREXIO_SUCCESS);
+  assert (een[0] == 11.0);
+  assert (een[1] == 12.0);
+  assert (een[2] == 13.0);
+  assert (een[3] == 14.0);
+  assert (een[4] == 15.0);
+  assert (een[5] == 16.0);
+
+  int en_nucleus [3] = { 0, 0, 0 };
+  rc = trexio_read_jastrow_en_nucleus(file, en_nucleus);
+  assert (rc == TREXIO_SUCCESS);
+  assert (en_nucleus[0] == 0);
+  assert (en_nucleus[1] == 1);
+  assert (en_nucleus[2] == 2);
+
+  int een_nucleus [6] = { 0, 0, 0, 0, 0, 0 };
+  rc = trexio_read_jastrow_een_nucleus(file, een_nucleus);
+  assert (rc == TREXIO_SUCCESS);
+  assert (een_nucleus[0] == 0);
+  assert (een_nucleus[1] == 0);
+  assert (een_nucleus[2] == 1);
+  assert (een_nucleus[3] == 1);
+  assert (een_nucleus[4] == 2);
+  assert (een_nucleus[5] == 2);
+
+  double ee_scaling = 0.0;
+  rc = trexio_read_jastrow_ee_scaling(file, &ee_scaling);
+  assert (rc == TREXIO_SUCCESS);
+  assert (ee_scaling == 1.0);
+
+  double en_scaling[3] = { 0.5, 1.0, 0.5 };
+  rc = trexio_read_jastrow_en_scaling(file, en_scaling);
+  assert (rc == TREXIO_SUCCESS);
+  assert (en_scaling[0] == 0.5);
+  assert (en_scaling[1] == 1.0);
+  assert (en_scaling[2] == 0.5);
+
+  rc = trexio_close(file);
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(){
+
+/*============== Test launcher ================*/
+
+  int rc;
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write_jastrow (TREXIO_FILE, TEST_BACKEND);
+  test_read_jastrow  (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
diff --git a/tests/io_jastrow_hdf5.c b/tests/io_jastrow_hdf5.c
index 4dfb9a0d..8804096e 100644
--- a/tests/io_jastrow_hdf5.c
+++ b/tests/io_jastrow_hdf5.c
@@ -1,198 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_jastrow"
+#include "test_macros.h"
+#include "io_jastrow.c"
 
-#define TEST_BACKEND  TREXIO_HDF5
-#define TREXIO_FILE   "test_jastrow.h5"
-#define RM_COMMAND    "rm -f -- " TREXIO_FILE
-
-static int test_write_jastrow (const char* file_name, const back_end_t backend) {
-
-/* Try to write an array of sparse data into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-#define nucleus_num  3
-#define ee_num 2
-#define en_num 3
-#define een_num 6
-
-  rc = trexio_write_nucleus_num(file, nucleus_num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_jastrow_type(file, "CHAMP", 6);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_jastrow_ee_num(file, ee_num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_jastrow_en_num(file, en_num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_jastrow_een_num(file, een_num);
-  assert (rc == TREXIO_SUCCESS);
-
-  double ee [2] = { 0.5, 2. };
-  rc = trexio_write_jastrow_ee(file, ee);
-  assert (rc == TREXIO_SUCCESS);
-
-  double en [3] = { 1., 2., 3. };
-  rc = trexio_write_jastrow_en(file, en);
-  assert (rc == TREXIO_SUCCESS);
-
-  double een [6] = { 11., 12., 13., 14., 15., 16. };
-  rc = trexio_write_jastrow_een(file, een);
-  assert (rc == TREXIO_SUCCESS);
-
-  int en_nucleus [3] = { 0, 1, 2 };
-  rc = trexio_write_jastrow_en_nucleus(file, en_nucleus);
-  assert (rc == TREXIO_SUCCESS);
-
-  int een_nucleus [6] = { 0, 0, 1, 1, 2, 2 };
-  rc = trexio_write_jastrow_een_nucleus(file, een_nucleus);
-  assert (rc == TREXIO_SUCCESS);
-
-  double ee_scaling = 1.0;
-  rc = trexio_write_jastrow_ee_scaling(file, ee_scaling);
-  assert (rc == TREXIO_SUCCESS);
-
-  double en_scaling[3] = { 0.5, 1.0, 0.5 };
-  rc = trexio_write_jastrow_en_scaling(file, en_scaling);
-  assert (rc == TREXIO_SUCCESS);
-
-#undef nucleus_num
-#undef ee_num
-#undef en_num
-#undef een_num
-
-  rc = trexio_close(file);
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_read_jastrow (const char* file_name, const back_end_t backend) {
-
-/* Try to read one chunk of dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  int nucleus_num = 0;
-  rc = trexio_read_nucleus_num(file, &nucleus_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (nucleus_num == 3);
-
-  char type[16] = "";
-  rc = trexio_read_jastrow_type(file, type, 16);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp("CHAMP",type) == 0);
-
-  int ee_num = 0;
-  rc = trexio_read_jastrow_ee_num(file, &ee_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (ee_num == 2);
-
-  int en_num = 0;
-  rc = trexio_read_jastrow_en_num(file, &en_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (en_num == nucleus_num);
-
-  int een_num = 0;
-  rc = trexio_read_jastrow_een_num(file, &een_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (een_num == 2*nucleus_num);
-
-  double ee [2] = { 0., 0. };
-  rc = trexio_read_jastrow_ee(file, ee);
-  assert (rc == TREXIO_SUCCESS);
-  assert (ee[0] == 0.5);
-  assert (ee[1] == 2.0);
-
-  double en [3] = { 0., 0., 0. };
-  rc = trexio_read_jastrow_en(file, en);
-  assert (rc == TREXIO_SUCCESS);
-  assert (en[0] == 1.0);
-  assert (en[1] == 2.0);
-  assert (en[2] == 3.0);
-
-  double een [6];
-  rc = trexio_read_jastrow_een(file, een);
-  assert (rc == TREXIO_SUCCESS);
-  assert (een[0] == 11.0);
-  assert (een[1] == 12.0);
-  assert (een[2] == 13.0);
-  assert (een[3] == 14.0);
-  assert (een[4] == 15.0);
-  assert (een[5] == 16.0);
-
-  int en_nucleus [3] = { 0, 0, 0 };
-  rc = trexio_read_jastrow_en_nucleus(file, en_nucleus);
-  assert (rc == TREXIO_SUCCESS);
-  assert (en_nucleus[0] == 0);
-  assert (en_nucleus[1] == 1);
-  assert (en_nucleus[2] == 2);
-
-  int een_nucleus [6] = { 0, 0, 0, 0, 0, 0 };
-  rc = trexio_read_jastrow_een_nucleus(file, een_nucleus);
-  assert (rc == TREXIO_SUCCESS);
-  assert (een_nucleus[0] == 0);
-  assert (een_nucleus[1] == 0);
-  assert (een_nucleus[2] == 1);
-  assert (een_nucleus[3] == 1);
-  assert (een_nucleus[4] == 2);
-  assert (een_nucleus[5] == 2);
-
-  double ee_scaling = 0.0;
-  rc = trexio_read_jastrow_ee_scaling(file, &ee_scaling);
-  assert (rc == TREXIO_SUCCESS);
-  assert (ee_scaling == 1.0);
-
-  double en_scaling[3] = { 0.5, 1.0, 0.5 };
-  rc = trexio_read_jastrow_en_scaling(file, en_scaling);
-  assert (rc == TREXIO_SUCCESS);
-  assert (en_scaling[0] == 0.5);
-  assert (en_scaling[1] == 1.0);
-  assert (en_scaling[2] == 0.5);
-
-  rc = trexio_close(file);
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(){
-
-/*============== Test launcher ================*/
-
-  int rc;
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_jastrow (TREXIO_FILE, TEST_BACKEND);
-  test_read_jastrow  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_jastrow_text.c b/tests/io_jastrow_text.c
index 80c81ea3..40f4b089 100644
--- a/tests/io_jastrow_text.c
+++ b/tests/io_jastrow_text.c
@@ -1,198 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_jastrow"
+#include "test_macros.h"
+#include "io_jastrow.c"
 
-#define TEST_BACKEND  TREXIO_TEXT
-#define TREXIO_FILE   "test_jastrow.dir"
-#define RM_COMMAND    "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write_jastrow (const char* file_name, const back_end_t backend) {
-
-/* Try to write an array of sparse data into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-#define nucleus_num  3
-#define ee_num 2
-#define en_num 3
-#define een_num 6
-
-  rc = trexio_write_nucleus_num(file, nucleus_num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_jastrow_type(file, "CHAMP", 6);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_jastrow_ee_num(file, ee_num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_jastrow_en_num(file, en_num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_jastrow_een_num(file, een_num);
-  assert (rc == TREXIO_SUCCESS);
-
-  double ee [2] = { 0.5, 2. };
-  rc = trexio_write_jastrow_ee(file, ee);
-  assert (rc == TREXIO_SUCCESS);
-
-  double en [3] = { 1., 2., 3. };
-  rc = trexio_write_jastrow_en(file, en);
-  assert (rc == TREXIO_SUCCESS);
-
-  double een [6] = { 11., 12., 13., 14., 15., 16. };
-  rc = trexio_write_jastrow_een(file, een);
-  assert (rc == TREXIO_SUCCESS);
-
-  int en_nucleus [3] = { 0, 1, 2 };
-  rc = trexio_write_jastrow_en_nucleus(file, en_nucleus);
-  assert (rc == TREXIO_SUCCESS);
-
-  int een_nucleus [6] = { 0, 0, 1, 1, 2, 2 };
-  rc = trexio_write_jastrow_een_nucleus(file, een_nucleus);
-  assert (rc == TREXIO_SUCCESS);
-
-  double ee_scaling = 1.0;
-  rc = trexio_write_jastrow_ee_scaling(file, ee_scaling);
-  assert (rc == TREXIO_SUCCESS);
-
-  double en_scaling[3] = { 0.5, 1.0, 0.5 };
-  rc = trexio_write_jastrow_en_scaling(file, en_scaling);
-  assert (rc == TREXIO_SUCCESS);
-
-#undef nucleus_num
-#undef ee_num
-#undef en_num
-#undef een_num
-
-  rc = trexio_close(file);
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-static int test_read_jastrow (const char* file_name, const back_end_t backend) {
-
-/* Try to read one chunk of dataset of sparse data in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  int nucleus_num = 0;
-  rc = trexio_read_nucleus_num(file, &nucleus_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (nucleus_num == 3);
-
-  char type[16] = "";
-  rc = trexio_read_jastrow_type(file, type, 16);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp("CHAMP",type) == 0);
-
-  int ee_num = 0;
-  rc = trexio_read_jastrow_ee_num(file, &ee_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (ee_num == 2);
-
-  int en_num = 0;
-  rc = trexio_read_jastrow_en_num(file, &en_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (en_num == nucleus_num);
-
-  int een_num = 0;
-  rc = trexio_read_jastrow_een_num(file, &een_num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (een_num == 2*nucleus_num);
-
-  double ee [2] = { 0., 0. };
-  rc = trexio_read_jastrow_ee(file, ee);
-  assert (rc == TREXIO_SUCCESS);
-  assert (ee[0] == 0.5);
-  assert (ee[1] == 2.0);
-
-  double en [3] = { 0., 0., 0. };
-  rc = trexio_read_jastrow_en(file, en);
-  assert (rc == TREXIO_SUCCESS);
-  assert (en[0] == 1.0);
-  assert (en[1] == 2.0);
-  assert (en[2] == 3.0);
-
-  double een [6];
-  rc = trexio_read_jastrow_een(file, een);
-  assert (rc == TREXIO_SUCCESS);
-  assert (een[0] == 11.0);
-  assert (een[1] == 12.0);
-  assert (een[2] == 13.0);
-  assert (een[3] == 14.0);
-  assert (een[4] == 15.0);
-  assert (een[5] == 16.0);
-
-  int en_nucleus [3] = { 0, 0, 0 };
-  rc = trexio_read_jastrow_en_nucleus(file, en_nucleus);
-  assert (rc == TREXIO_SUCCESS);
-  assert (en_nucleus[0] == 0);
-  assert (en_nucleus[1] == 1);
-  assert (en_nucleus[2] == 2);
-
-  int een_nucleus [6] = { 0, 0, 0, 0, 0, 0 };
-  rc = trexio_read_jastrow_een_nucleus(file, een_nucleus);
-  assert (rc == TREXIO_SUCCESS);
-  assert (een_nucleus[0] == 0);
-  assert (een_nucleus[1] == 0);
-  assert (een_nucleus[2] == 1);
-  assert (een_nucleus[3] == 1);
-  assert (een_nucleus[4] == 2);
-  assert (een_nucleus[5] == 2);
-
-  double ee_scaling = 0.0;
-  rc = trexio_read_jastrow_ee_scaling(file, &ee_scaling);
-  assert (rc == TREXIO_SUCCESS);
-  assert (ee_scaling == 1.0);
-
-  double en_scaling[3] = { 0.5, 1.0, 0.5 };
-  rc = trexio_read_jastrow_en_scaling(file, en_scaling);
-  assert (rc == TREXIO_SUCCESS);
-  assert (en_scaling[0] == 0.5);
-  assert (en_scaling[1] == 1.0);
-  assert (en_scaling[2] == 0.5);
-
-  rc = trexio_close(file);
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(){
-
-/*============== Test launcher ================*/
-
-  int rc;
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_jastrow (TREXIO_FILE, TEST_BACKEND);
-  test_read_jastrow  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_num.c b/tests/io_num.c
new file mode 100644
index 00000000..fe55f830
--- /dev/null
+++ b/tests/io_num.c
@@ -0,0 +1,150 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+static int test_write_num (const char* file_name, const back_end_t backend) {
+
+/* Try to write a dimensioning attribute (num variable) into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 12;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // write numerical attribute in an empty file
+  rc = trexio_write_nucleus_num(file, num);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_nucleus_repulsion(file, 2.14171677);
+  assert (rc == TREXIO_SUCCESS);
+
+  // attempt to write 0 as dimensioning variable in an empty file; should FAIL and return TREXIO_INVALID_ARG_2
+  rc = trexio_write_mo_num(file, 0);
+  assert (rc == TREXIO_INVALID_NUM);
+
+  // write numerical attribute ao_cartesian as 0
+  rc = trexio_write_ao_cartesian(file, 0);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_has_num (const char* file_name, const back_end_t backend) {
+
+/* Try to check the existence of a dimensioning attribute (num variable) in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // check that the previously written num variable exists
+  rc = trexio_has_nucleus_num(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_has_nucleus_repulsion(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // check that the num variable does not exist
+  rc = trexio_has_mo_num(file);
+  assert (rc == TREXIO_HAS_NOT);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_read_num (const char* file_name, const back_end_t backend) {
+
+/* Try to read a dimensioning attribute (num variable) from the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be read
+  int num;
+  int cartesian;
+  float repulsion_32;
+  double repulsion_64, d;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // read numerical attribute from the file
+  rc = trexio_read_nucleus_num(file, &num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (num == 12);
+
+  rc = trexio_read_nucleus_repulsion_32(file, &repulsion_32);
+  assert (rc == TREXIO_SUCCESS);
+  d = repulsion_32 - 2.14171677;
+  assert( d*d < 1.e-8 );
+
+  rc = trexio_read_nucleus_repulsion_64(file, &repulsion_64);
+  assert (rc == TREXIO_SUCCESS);
+  d = repulsion_64 - 2.14171677;
+  assert( d*d < 1.e-14 );
+
+  // read non-existing numerical attribute from the file
+  rc = trexio_read_mo_num(file, &num);
+  assert (rc == TREXIO_ATTR_MISSING);
+
+  // read ao_cartesian (zero) value from the file
+  rc = trexio_read_ao_cartesian(file, &cartesian);
+  assert (rc == TREXIO_SUCCESS);
+  assert (cartesian == 0);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write_num (TREXIO_FILE, TEST_BACKEND);
+  test_has_num   (TREXIO_FILE, TEST_BACKEND);
+  test_read_num  (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
diff --git a/tests/io_num_hdf5.c b/tests/io_num_hdf5.c
index 32de679c..6c6f16b1 100644
--- a/tests/io_num_hdf5.c
+++ b/tests/io_num_hdf5.c
@@ -1,154 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_num"
+#include "test_macros.h"
+#include "io_num.c"
 
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_num.h5"
-#define RM_COMMAND 	"rm -rf " TREXIO_FILE
-
-static int test_write_num (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dimensioning attribute (num variable) into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_repulsion(file, 2.14171677);
-  assert (rc == TREXIO_SUCCESS);
-
-  // attempt to write 0 as dimensioning variable in an empty file; should FAIL and return TREXIO_INVALID_ARG_2
-  rc = trexio_write_mo_num(file, 0);
-  assert (rc == TREXIO_INVALID_NUM);
-
-  // write numerical attribute ao_cartesian as 0
-  rc = trexio_write_ao_cartesian(file, 0);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_num (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dimensioning attribute (num variable) in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written num variable exists
-  rc = trexio_has_nucleus_num(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_has_nucleus_repulsion(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that the num variable does not exist
-  rc = trexio_has_mo_num(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_num (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dimensioning attribute (num variable) from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num;
-  int cartesian;
-  float repulsion_32;
-  double repulsion_64, d;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_nucleus_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  rc = trexio_read_nucleus_repulsion_32(file, &repulsion_32);
-  assert (rc == TREXIO_SUCCESS);
-  d = repulsion_32 - 2.14171677;
-  assert( d*d < 1.e-8 );
-
-  rc = trexio_read_nucleus_repulsion_64(file, &repulsion_64);
-  assert (rc == TREXIO_SUCCESS);
-  d = repulsion_64 - 2.14171677;
-  assert( d*d < 1.e-14 );
-
-  // read non-existing numerical attribute from the file
-  rc = trexio_read_mo_num(file, &num);
-  assert (rc == TREXIO_ATTR_MISSING);
-
-  // read ao_cartesian (zero) value from the file
-  rc = trexio_read_ao_cartesian(file, &cartesian);
-  assert (rc == TREXIO_SUCCESS);
-  assert (cartesian == 0);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_num (TREXIO_FILE, TEST_BACKEND);
-  test_has_num   (TREXIO_FILE, TEST_BACKEND);
-  test_read_num  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_num_text.c b/tests/io_num_text.c
index 94fd4888..3102d6d6 100644
--- a/tests/io_num_text.c
+++ b/tests/io_num_text.c
@@ -1,154 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_num"
+#include "test_macros.h"
+#include "io_num.c"
 
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_num.dir"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write_num (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dimensioning attribute (num variable) into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_repulsion(file, 2.14171677);
-  assert (rc == TREXIO_SUCCESS);
-
-  // attempt to write 0 as dimensioning variable in an empty file; should FAIL and return TREXIO_INVALID_ARG_2
-  rc = trexio_write_mo_num(file, 0);
-  assert (rc == TREXIO_INVALID_NUM);
-
-  // write numerical attribute ao_cartesian as 0
-  rc = trexio_write_ao_cartesian(file, 0);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_num (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dimensioning attribute (num variable) in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written num variable exists
-  rc = trexio_has_nucleus_num(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_has_nucleus_repulsion(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that the num variable does not exist
-  rc = trexio_has_mo_num(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_num (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dimensioning attribute (num variable) from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num;
-  int cartesian;
-  float repulsion_32;
-  double repulsion_64, d;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_nucleus_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  rc = trexio_read_nucleus_repulsion_32(file, &repulsion_32);
-  assert (rc == TREXIO_SUCCESS);
-  d = repulsion_32 - 2.14171677;
-  assert( d*d < 1.e-8 );
-
-  rc = trexio_read_nucleus_repulsion_64(file, &repulsion_64);
-  assert (rc == TREXIO_SUCCESS);
-  d = repulsion_64 - 2.14171677;
-  assert( d*d < 1.e-14 );
-
-  // read non-existing numerical attribute from the file
-  rc = trexio_read_mo_num(file, &num);
-  assert (rc == TREXIO_ATTR_MISSING);
-
-  // read ao_cartesian (zero) value from the file
-  rc = trexio_read_ao_cartesian(file, &cartesian);
-  assert (rc == TREXIO_SUCCESS);
-  assert (cartesian == 0);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_num (TREXIO_FILE, TEST_BACKEND);
-  test_has_num   (TREXIO_FILE, TEST_BACKEND);
-  test_read_num  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_safe_dset_float.c b/tests/io_safe_dset_float.c
new file mode 100644
index 00000000..c4434b97
--- /dev/null
+++ b/tests/io_safe_dset_float.c
@@ -0,0 +1,161 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+static int test_write_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to write a dataset with floating point values into the TREXIO file using safe API */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 12;
+  double coord[36] = {
+  0.00000000 ,  1.39250319 ,  0.00000000 ,
+ -1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -1.20594314 , -0.69625160 ,  0.00000000 ,
+  0.00000000 , -1.39250319 ,  0.00000000 ,
+  1.20594314 , -0.69625160 ,  0.00000000 ,
+  1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -2.14171677 ,  1.23652075 ,  0.00000000 ,
+ -2.14171677 , -1.23652075 ,  0.00000000 ,
+  0.00000000 , -2.47304151 ,  0.00000000 ,
+  2.14171677 , -1.23652075 ,  0.00000000 ,
+  2.14171677 ,  1.23652075 ,  0.00000000 ,
+  0.00000000 ,  2.47304151 ,  0.00000000 ,
+  };
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // write numerical attribute in an empty file
+  rc = trexio_write_nucleus_num(file, num);
+  assert (rc == TREXIO_SUCCESS);
+  
+  /* write numerical dataset with an unsafe dimension
+   * this should return TREXIO_UNSAFE_ARRAY_DIM indicating
+   * that access beyong allocated memory is likely to occur */
+  uint64_t dim_unsafe = num * 12;
+  rc = trexio_write_safe_nucleus_coord(file, coord, dim_unsafe);
+  assert (rc == TREXIO_UNSAFE_ARRAY_DIM);
+
+  /* write numerical dataset with a safe dimension
+   * this should return TREXIO_SUCCESS */
+  uint64_t dim_safe = num * 3;
+  rc = trexio_write_safe_nucleus_coord(file, coord, dim_safe);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_has_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to check the existence of a dataset in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // check that the previously written dataset exists
+  rc = trexio_has_nucleus_coord(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_read_dset (const char* file_name, const back_end_t backend) {
+
+/* Try to read a dataset with floating point values from the TREXIO file using safe API */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be read
+  int num;
+  double* coord;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // read numerical attribute from the file
+  rc = trexio_read_nucleus_num(file, &num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (num == 12);
+
+  // read numerical (floating point) dataset from the file
+  coord = (double*) calloc(3*num, sizeof(double));
+
+  /* write numerical dataset with an unsafe dimension
+   * this should return TREXIO_UNSAFE_ARRAY_DIM indicating
+   * that access beyong allocated memory is likely to occur */
+  uint64_t dim_unsafe = num * 12;
+  rc = trexio_read_safe_nucleus_coord(file, coord, dim_unsafe);
+  assert (rc == TREXIO_UNSAFE_ARRAY_DIM);
+
+  /* write numerical dataset with a safe dimension
+   * this should return TREXIO_SUCCESS */
+  uint64_t dim_safe = num * 3;
+  rc = trexio_read_safe_nucleus_coord(file, coord, dim_safe);
+  assert (rc == TREXIO_SUCCESS);
+
+  double x = coord[30] - 2.14171677;
+  assert( x*x < 1.e-14 );
+  free(coord);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write_dset (TREXIO_FILE, TEST_BACKEND);
+  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
+  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
+
+
diff --git a/tests/io_safe_dset_float_hdf5.c b/tests/io_safe_dset_float_hdf5.c
index 318ed4a1..da8afe11 100644
--- a/tests/io_safe_dset_float_hdf5.c
+++ b/tests/io_safe_dset_float_hdf5.c
@@ -1,165 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_safe_dset_f.h5"
-#define RM_COMMAND 	"rm -rf " TREXIO_FILE
-
-static int test_write_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dataset with floating point values into the TREXIO file using safe API */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  double coord[36] = {
-  0.00000000 ,  1.39250319 ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000 ,
-  1.20594314 ,  0.69625160 ,  0.00000000 ,
- -2.14171677 ,  1.23652075 ,  0.00000000 ,
- -2.14171677 , -1.23652075 ,  0.00000000 ,
-  0.00000000 , -2.47304151 ,  0.00000000 ,
-  2.14171677 , -1.23652075 ,  0.00000000 ,
-  2.14171677 ,  1.23652075 ,  0.00000000 ,
-  0.00000000 ,  2.47304151 ,  0.00000000 ,
-  };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-  
-  /* write numerical dataset with an unsafe dimension
-   * this should return TREXIO_UNSAFE_ARRAY_DIM indicating
-   * that access beyong allocated memory is likely to occur */
-  uint64_t dim_unsafe = num * 12;
-  rc = trexio_write_safe_nucleus_coord(file, coord, dim_unsafe);
-  assert (rc == TREXIO_UNSAFE_ARRAY_DIM);
-
-  /* write numerical dataset with a safe dimension
-   * this should return TREXIO_SUCCESS */
-  uint64_t dim_safe = num * 3;
-  rc = trexio_write_safe_nucleus_coord(file, coord, dim_safe);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written dataset exists
-  rc = trexio_has_nucleus_coord(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dataset with floating point values from the TREXIO file using safe API */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num;
-  double* coord;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_nucleus_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  // read numerical (floating point) dataset from the file
-  coord = (double*) calloc(3*num, sizeof(double));
-
-  /* write numerical dataset with an unsafe dimension
-   * this should return TREXIO_UNSAFE_ARRAY_DIM indicating
-   * that access beyong allocated memory is likely to occur */
-  uint64_t dim_unsafe = num * 12;
-  rc = trexio_read_safe_nucleus_coord(file, coord, dim_unsafe);
-  assert (rc == TREXIO_UNSAFE_ARRAY_DIM);
-
-  /* write numerical dataset with a safe dimension
-   * this should return TREXIO_SUCCESS */
-  uint64_t dim_safe = num * 3;
-  rc = trexio_read_safe_nucleus_coord(file, coord, dim_safe);
-  assert (rc == TREXIO_SUCCESS);
-
-  double x = coord[30] - 2.14171677;
-  assert( x*x < 1.e-14 );
-  free(coord);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_dset (TREXIO_FILE, TEST_BACKEND);
-  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
-
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_safe_dset_float"
+#include "test_macros.h"
+#include "io_safe_dset_float.c"
 
diff --git a/tests/io_safe_dset_float_text.c b/tests/io_safe_dset_float_text.c
index bbd9b6bc..7b5cc6ea 100644
--- a/tests/io_safe_dset_float_text.c
+++ b/tests/io_safe_dset_float_text.c
@@ -1,163 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_safe_dset_float"
+#include "test_macros.h"
+#include "io_safe_dset_float.c"
 
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_safe_dset_f.dir"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to write a dataset with floating point values into the TREXIO file using safe API */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  double coord[36] = {
-  0.00000000 ,  1.39250319 ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000 ,
-  1.20594314 ,  0.69625160 ,  0.00000000 ,
- -2.14171677 ,  1.23652075 ,  0.00000000 ,
- -2.14171677 , -1.23652075 ,  0.00000000 ,
-  0.00000000 , -2.47304151 ,  0.00000000 ,
-  2.14171677 , -1.23652075 ,  0.00000000 ,
-  2.14171677 ,  1.23652075 ,  0.00000000 ,
-  0.00000000 ,  2.47304151 ,  0.00000000 ,
-  };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write numerical attribute in an empty file
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  /* write numerical dataset with an unsafe dimension
-   * this should return TREXIO_UNSAFE_ARRAY_DIM indicating
-   * that access beyong allocated memory is likely to occur */
-  uint64_t dim_unsafe = num * 12;
-  rc = trexio_write_safe_nucleus_coord(file, coord, dim_unsafe);
-  assert (rc == TREXIO_UNSAFE_ARRAY_DIM);
-
-  /* write numerical dataset with a safe dimension
-   * this should return TREXIO_SUCCESS */
-  uint64_t dim_safe = num * 3;
-  rc = trexio_write_safe_nucleus_coord(file, coord, dim_safe);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a dataset in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written dataset exists
-  rc = trexio_has_nucleus_coord(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_dset (const char* file_name, const back_end_t backend) {
-
-/* Try to read a dataset with floating point values from the TREXIO file using safe API */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  int num;
-  double* coord;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read numerical attribute from the file
-  rc = trexio_read_nucleus_num(file, &num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 12);
-
-  // read numerical (floating point) dataset from the file
-  coord = (double*) calloc(3*num, sizeof(double));
-
-  /* write numerical dataset with an unsafe dimension
-   * this should return TREXIO_UNSAFE_ARRAY_DIM indicating
-   * that access beyong allocated memory is likely to occur */
-  uint64_t dim_unsafe = num * 12;
-  rc = trexio_read_safe_nucleus_coord(file, coord, dim_unsafe);
-  assert (rc == TREXIO_UNSAFE_ARRAY_DIM);
-
-  /* write numerical dataset with a safe dimension
-   * this should return TREXIO_SUCCESS */
-  uint64_t dim_safe = num * 3;
-  rc = trexio_read_safe_nucleus_coord(file, coord, dim_safe);
-  assert (rc == TREXIO_SUCCESS);
-
-  double x = coord[30] - 2.14171677;
-  assert( x*x < 1.e-14 );
-  free(coord);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_dset (TREXIO_FILE, TEST_BACKEND);
-  test_has_dset   (TREXIO_FILE, TEST_BACKEND);
-  test_read_dset  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/io_str.c b/tests/io_str.c
new file mode 100644
index 00000000..a0fdfab7
--- /dev/null
+++ b/tests/io_str.c
@@ -0,0 +1,129 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int test_write_str (const char* file_name, const back_end_t backend) {
+
+/* Try to write a string attribute (single variable-length string) into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  const char* sym = "B3U with some comments";
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // write string attribute in an empty file
+  int max_str_len = 32;
+  rc = trexio_write_nucleus_point_group(file, sym, max_str_len);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_has_str (const char* file_name, const back_end_t backend) {
+
+/* Try to check the existence of a string attribute in the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // check that the previously written string attribute exists
+  rc = trexio_has_nucleus_point_group(file);
+  assert (rc == TREXIO_SUCCESS);
+
+  // check that another string attribute does not exist
+  rc = trexio_has_mo_type(file);
+  assert (rc == TREXIO_HAS_NOT);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_read_str (const char* file_name, const back_end_t backend) {
+
+/* Try to read a string attribute from the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be read
+  char* sym;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // read string attribute from the file
+  int max_str_len = 32;
+  sym = (char*) malloc(max_str_len*sizeof(char));
+
+  rc = trexio_read_nucleus_point_group(file, sym, max_str_len);
+  assert (rc == TREXIO_SUCCESS);
+
+  char * pch;
+  pch = strtok(sym, " ");
+  assert (strcmp(pch, "B3U") == 0);
+  /* alternative test when 3 symbols are read from the file to sym */
+  /*rc = trexio_read_nucleus_point_group(file, sym, 3);
+  assert (rc == TREXIO_SUCCESS);
+  assert (strcmp(sym, "B3U") == 0 );*/
+  free(sym);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write_str (TREXIO_FILE, TEST_BACKEND);
+  test_has_str   (TREXIO_FILE, TEST_BACKEND);
+  test_read_str  (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
+
+
diff --git a/tests/io_str_hdf5.c b/tests/io_str_hdf5.c
index eaafff08..58f06952 100644
--- a/tests/io_str_hdf5.c
+++ b/tests/io_str_hdf5.c
@@ -1,133 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_str.h5"
-#define RM_COMMAND 	"rm -rf " TREXIO_FILE
-
-static int test_write_str (const char* file_name, const back_end_t backend) {
-
-/* Try to write a string attribute (single variable-length string) into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  const char* sym = "B3U with some comments";
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write string attribute in an empty file
-  int max_str_len = 32;
-  rc = trexio_write_nucleus_point_group(file, sym, max_str_len);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_str (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a string attribute in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written string attribute exists
-  rc = trexio_has_nucleus_point_group(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that another string attribute does not exist
-  rc = trexio_has_mo_type(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_str (const char* file_name, const back_end_t backend) {
-
-/* Try to read a string attribute from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  char* sym;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read string attribute from the file
-  int max_str_len = 32;
-  sym = (char*) malloc(max_str_len*sizeof(char));
-
-  rc = trexio_read_nucleus_point_group(file, sym, max_str_len);
-  assert (rc == TREXIO_SUCCESS);
-
-  char * pch;
-  pch = strtok(sym, " ");
-  assert (strcmp(pch, "B3U") == 0);
-  /* alternative test when 3 symbols are read from the file to sym */
-  /*rc = trexio_read_nucleus_point_group(file, sym, 3);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp(sym, "B3U") == 0 );*/
-  free(sym);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_str (TREXIO_FILE, TEST_BACKEND);
-  test_has_str   (TREXIO_FILE, TEST_BACKEND);
-  test_read_str  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
-
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "io_str"
+#include "test_macros.h"
+#include "io_str.c"
 
diff --git a/tests/io_str_text.c b/tests/io_str_text.c
index 4aad28f7..888d35ba 100644
--- a/tests/io_str_text.c
+++ b/tests/io_str_text.c
@@ -1,131 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "io_str"
+#include "test_macros.h"
+#include "io_str.c"
 
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_str.dir"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write_str (const char* file_name, const back_end_t backend) {
-
-/* Try to write a string attribute (single variable-length string) into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  const char* sym = "B3U with some comments";
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write string attribute in an empty file
-  int max_str_len = 32;
-  rc = trexio_write_nucleus_point_group(file, sym, max_str_len);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_has_str (const char* file_name, const back_end_t backend) {
-
-/* Try to check the existence of a string attribute in the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written string attribute exists
-  rc = trexio_has_nucleus_point_group(file);
-  assert (rc == TREXIO_SUCCESS);
-
-  // check that another string attribute does not exist
-  rc = trexio_has_mo_type(file);
-  assert (rc == TREXIO_HAS_NOT);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_read_str (const char* file_name, const back_end_t backend) {
-
-/* Try to read a string attribute from the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be read
-  char* sym;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read string attribute from the file
-  int max_str_len = 32;
-  sym = (char*) malloc(max_str_len*sizeof(char));
-
-  rc = trexio_read_nucleus_point_group(file, sym, max_str_len);
-  assert (rc == TREXIO_SUCCESS);
-
-  char * pch;
-  pch = strtok(sym, " ");
-  assert (strcmp(pch, "B3U") == 0);
-  /* alternative test when 3 symbols are read from the file to sym */
-  /*rc = trexio_read_nucleus_point_group(file, sym, 3);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp(sym, "B3U") == 0 );*/
-  free(sym);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write_str (TREXIO_FILE, TEST_BACKEND);
-  test_has_str   (TREXIO_FILE, TEST_BACKEND);
-  test_read_str  (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/open.c b/tests/open.c
new file mode 100644
index 00000000..db0bba76
--- /dev/null
+++ b/tests/open.c
@@ -0,0 +1,160 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#define TREXIO_VOID 	"non_existing_" TREXIO_FILE
+
+
+static int test_open_w (const char* file_name, const back_end_t backend) {
+
+/* Try to open the TREXIO file in 'write' mode */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_open_r (const char* file_name, const back_end_t backend) {
+
+/* Try to open the TREXIO file in 'read' mode */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_open_auto (const char* file_name) {
+
+/* Try to open the TREXIO file in 'read' mode */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'r', TREXIO_AUTO, &rc);
+  assert (file != NULL);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_open_errors (const back_end_t backend) {
+
+/* Try to call trexio_open with bad arguments */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // open non-existing file in 'r' (read) mode, should return TREXIO_OPEN_ERROR
+  file = trexio_open(TREXIO_VOID, 'r', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_OPEN_ERROR);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open file with empty file name, should return TREXIO_INVALID_ARG_1
+  file = trexio_open("", 'w', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_1);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open existing file in non-supported I/O mode, should return TREXIO_INVALID_ARG_2
+  file = trexio_open(TREXIO_FILE, 'k', backend, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_2);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+  // open existing file with non-supported back end, should return TREXIO_INVALID_ARG_3
+  file = trexio_open(TREXIO_FILE, 'w', 666, &rc);
+  assert (file == NULL);
+  assert (rc == TREXIO_INVALID_ARG_3);
+  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_inquire (const back_end_t backend) {
+
+/* Try to call trexio_inquire function */
+
+  trexio_exit_code rc;
+
+/*================= START OF TEST ==================*/
+
+  // inquire non-existing file
+  rc = trexio_inquire(TREXIO_VOID);
+  assert (rc == TREXIO_FAILURE);
+
+  // inquire existing file
+  rc = trexio_inquire(TREXIO_FILE);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_open_w     (TREXIO_FILE, TEST_BACKEND);
+  test_open_r     (TREXIO_FILE, TEST_BACKEND);
+  test_open_auto  (TREXIO_FILE);
+  test_open_errors(TEST_BACKEND);
+  test_inquire    (TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
diff --git a/tests/open_hdf5.c b/tests/open_hdf5.c
index d0a65810..029347d4 100644
--- a/tests/open_hdf5.c
+++ b/tests/open_hdf5.c
@@ -1,163 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "open"
+#include "test_macros.h"
+#include "open.c"
 
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_open.h5"
-#define TREXIO_VOID 	"non_existing_" TREXIO_FILE
-#define RM_COMMAND 	"rm -rf " TREXIO_FILE
-
-
-static int test_open_w (const char* file_name, const back_end_t backend) {
-
-/* Try to open the TREXIO file in 'write' mode */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_open_r (const char* file_name, const back_end_t backend) {
-
-/* Try to open the TREXIO file in 'read' mode */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_open_auto (const char* file_name) {
-
-/* Try to open the TREXIO file in 'read' mode */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'r', TREXIO_AUTO, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_open_errors (const back_end_t backend) {
-
-/* Try to call trexio_open with bad arguments */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open non-existing file in 'r' (read) mode, should return TREXIO_OPEN_ERROR
-  file = trexio_open(TREXIO_VOID, 'r', backend, &rc);
-  assert (file == NULL);
-  assert (rc == TREXIO_OPEN_ERROR);
-  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
-
-  // open file with empty file name, should return TREXIO_INVALID_ARG_1
-  file = trexio_open("", 'w', backend, &rc);
-  assert (file == NULL);
-  assert (rc == TREXIO_INVALID_ARG_1);
-  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
-
-  // open existing file in non-supported I/O mode, should return TREXIO_INVALID_ARG_2
-  file = trexio_open(TREXIO_FILE, 'k', backend, &rc);
-  assert (file == NULL);
-  assert (rc == TREXIO_INVALID_ARG_2);
-  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
-
-  // open existing file with non-supported back end, should return TREXIO_INVALID_ARG_3
-  file = trexio_open(TREXIO_FILE, 'w', 666, &rc);
-  assert (file == NULL);
-  assert (rc == TREXIO_INVALID_ARG_3);
-  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_inquire (const back_end_t backend) {
-
-/* Try to call trexio_inquire function */
-
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // inquire non-existing file
-  rc = trexio_inquire(TREXIO_VOID);
-  assert (rc == TREXIO_FAILURE);
-
-  // inquire existing file
-  rc = trexio_inquire(TREXIO_FILE);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_open_w     (TREXIO_FILE, TEST_BACKEND);
-  test_open_r     (TREXIO_FILE, TEST_BACKEND);
-  test_open_auto  (TREXIO_FILE);
-  test_open_errors(TEST_BACKEND);
-  test_inquire    (TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/open_text.c b/tests/open_text.c
index 4e435017..a4f3cd99 100644
--- a/tests/open_text.c
+++ b/tests/open_text.c
@@ -1,163 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "open"
+#include "test_macros.h"
+#include "open.c"
 
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_open.dir"
-#define TREXIO_VOID 	"non_existing_" TREXIO_FILE
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-
-static int test_open_w (const char* file_name, const back_end_t backend) {
-
-/* Try to open the TREXIO file in 'write' mode */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_open_r (const char* file_name, const back_end_t backend) {
-
-/* Try to open the TREXIO file in 'read' mode */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_open_auto (const char* file_name) {
-
-/* Try to open the TREXIO file in 'read' mode */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'r', TREXIO_AUTO, &rc);
-  assert (file != NULL);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_open_errors (const back_end_t backend) {
-
-/* Try to call trexio_open with bad arguments */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // open non-existing file in 'r' (read) mode, should return TREXIO_OPEN_ERROR
-  file = trexio_open(TREXIO_VOID, 'r', backend, &rc);
-  assert (file == NULL);
-  assert (rc == TREXIO_OPEN_ERROR);
-  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
-
-  // open file with empty file name, should return TREXIO_INVALID_ARG_1
-  file = trexio_open("", 'w', backend, &rc);
-  assert (file == NULL);
-  assert (rc == TREXIO_INVALID_ARG_1);
-  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
-
-  // open existing file in non-supported I/O mode, should return TREXIO_INVALID_ARG_2
-  file = trexio_open(TREXIO_FILE, 'k', backend, &rc);
-  assert (file == NULL);
-  assert (rc == TREXIO_INVALID_ARG_2);
-  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
-
-  // open existing file with non-supported back end, should return TREXIO_INVALID_ARG_3
-  file = trexio_open(TREXIO_FILE, 'w', 666, &rc);
-  assert (file == NULL);
-  assert (rc == TREXIO_INVALID_ARG_3);
-  fprintf(stderr, "%s \n", trexio_string_of_error(rc));
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_inquire (const back_end_t backend) {
-
-/* Try to call trexio_inquire function */
-
-  trexio_exit_code rc;
-
-/*================= START OF TEST ==================*/
-
-  // inquire non-existing file
-  rc = trexio_inquire(TREXIO_VOID);
-  assert (rc == TREXIO_FAILURE);
-
-  // inquire existing file
-  rc = trexio_inquire(TREXIO_FILE);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_open_w     (TREXIO_FILE, TEST_BACKEND);
-  test_open_r     (TREXIO_FILE, TEST_BACKEND);
-  test_open_auto  (TREXIO_FILE);
-  test_open_errors(TEST_BACKEND);
-  test_inquire    (TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/overwrite_all.c b/tests/overwrite_all.c
new file mode 100644
index 00000000..b2236d7e
--- /dev/null
+++ b/tests/overwrite_all.c
@@ -0,0 +1,262 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+static int test_write (const char* file_name, const back_end_t backend) {
+
+/* Try to write a full set of data (num+dset_num+str+dset_str) related to benzene molecule into the TREXIO file */
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 12;
+  double coord[36] = {
+  0.00000000 ,  1.39250319 ,  0.00000000 ,
+ -1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -1.20594314 , -0.69625160 ,  0.00000000 ,
+  0.00000000 , -1.39250319 ,  0.00000000 ,
+  1.20594314 , -0.69625160 ,  0.00000000 ,
+  1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -2.14171677 ,  1.23652075 ,  0.00000000 ,
+ -2.14171677 , -1.23652075 ,  0.00000000 ,
+  0.00000000 , -2.47304151 ,  0.00000000 ,
+  2.14171677 , -1.23652075 ,  0.00000000 ,
+  2.14171677 ,  1.23652075 ,  0.00000000 ,
+  0.00000000 ,  2.47304151 ,  0.00000000 ,
+  };
+  const char* sym = "D6h";
+  const char* labels[] = {"C" ,
+                          "C" ,
+                          "C" ,
+                          "C" ,
+                          "C" ,
+                          "C" ,
+                          "H" ,
+                          "H" ,
+                          "H" ,
+                          "H" ,
+                          "H" ,
+                          "H" };
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // write the data
+  rc = trexio_write_nucleus_num(file, num);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_nucleus_coord(file, coord);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_nucleus_point_group(file, sym, 4);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_nucleus_label(file, labels, 2);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_overwrite_unsafe (const char* file_name, const back_end_t backend) {
+
+/* Try to overwrite the data that already exists in the TREXIO file which is open in UNSAFE mode*/
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 5;
+  double coord[15] = {
+  0.00000000 ,  666.666    ,  0.00000000 ,
+ -1.20594314 ,  0.69625160 ,  0.00000000 ,
+ -1.20594314 , -0.69625160 ,  0.00000000 ,
+  0.00000000 , -1.39250319 ,  0.00000000 ,
+  1.20594314 , -0.69625160 ,  0.00000000
+  };
+  const char* sym = "Unknown";
+  const char* labels[] = {"Ru" ,
+                          "U"  ,
+                          "Cl" ,
+                          "Na" ,
+                          "H" };
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'u', backend, &rc);
+  assert (file != NULL);
+
+  // check that the previously written data cannot be overwritten
+  rc = trexio_write_nucleus_num(file, num);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_nucleus_coord(file, coord);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_nucleus_point_group(file, sym, 16);
+  assert (rc == TREXIO_SUCCESS);
+
+  rc = trexio_write_nucleus_label(file, labels, 4);
+  assert (rc == TREXIO_SUCCESS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+static int test_overwrite_safe (const char* file_name, const back_end_t backend) {
+
+/* Try to overwrite the data that already exists in the TREXIO file which is open in SAFE mode*/
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  // parameters to be written
+  int num = 24;
+  double coord[3] = {
+  0.00000000 ,  666.666,  0.00000000 ,
+  };
+  const char* sym = "Unknown";
+  const char* labels[] = {"Ru" ,
+                          "U"  ,
+                          "Cl" ,
+                          "Na" ,
+                          "H" };
+
+/*================= START OF TEST ==================*/
+
+  // open file in 'write' mode
+  file = trexio_open(file_name, 'w', backend, &rc);
+  assert (file != NULL);
+
+  // check that the previously written data cannot be overwritten
+  rc = trexio_write_nucleus_num(file, num);
+  assert (rc == TREXIO_ATTR_ALREADY_EXISTS);
+
+  rc = trexio_write_nucleus_coord(file, coord);
+  assert (rc == TREXIO_DSET_ALREADY_EXISTS);
+
+  rc = trexio_write_nucleus_point_group(file, sym, 16);
+  assert (rc == TREXIO_ATTR_ALREADY_EXISTS);
+
+  rc = trexio_write_nucleus_label(file, labels, 4);
+  assert (rc == TREXIO_DSET_ALREADY_EXISTS);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST ==================*/
+
+  return 0;
+}
+
+
+int test_read(const char* file_name, const back_end_t backend) {
+
+/*========= Test read ===========*/
+
+  trexio_t* file = NULL;
+  trexio_exit_code rc;
+
+  int num;
+  double* coord;
+  char** label;
+  char* point_group;
+
+/*================= START OF TEST ==================*/
+
+  // open existing file on 'read' mode
+  file = trexio_open(file_name, 'r', backend, &rc);
+  assert (file != NULL);
+
+  // read nucleus_num
+  rc = trexio_read_nucleus_num(file,&num);
+  assert (rc == TREXIO_SUCCESS);
+  assert (num == 5);
+
+  // read nucleus_coord
+  coord = (double*) calloc(3*num, sizeof(double));
+  rc = trexio_read_nucleus_coord(file,coord);
+  assert (rc == TREXIO_SUCCESS);
+
+  double x = coord[1] - 666.666;
+  assert( x*x < 1.e-14);
+  free(coord);
+
+  // read nucleus_label
+  label = (char**) malloc(num*sizeof(char*));
+  for (int i=0; i<num; i++){
+    label[i] = (char*) malloc(32*sizeof(char));
+  }
+
+  rc = trexio_read_nucleus_label(file, label, 2);
+  assert (rc == TREXIO_SUCCESS);
+  assert (strcmp(label[0], "Ru")  == 0);
+  assert (strcmp(label[3], "Na") == 0);
+
+  for (int i=0; i<num; i++){
+    free(label[i]);
+  }
+  free(label);
+
+  point_group = (char*) malloc(32*sizeof(char));
+
+  rc = trexio_read_nucleus_point_group(file, point_group, 10);
+  assert (rc == TREXIO_SUCCESS);
+
+  char * pch;
+  pch = strtok(point_group, " ");
+  assert (strcmp(pch, "Unknown") == 0);
+  /* alternative test when 3 symbols are read from the file to point_group */
+  /*rc = trexio_read_nucleus_point_group(file, point_group, 3);
+  assert (rc == TREXIO_SUCCESS);
+  assert (strcmp(point_group, "B3U") == 0 );*/
+  free(point_group);
+
+  // close current session
+  rc = trexio_close(file);
+  assert (rc == TREXIO_SUCCESS);
+
+/*================= END OF TEST =====================*/
+
+  return 0;
+}
+
+
+int main(void) {
+
+/*============== Test launcher ================*/
+
+  int rc;
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  test_write            (TREXIO_FILE, TEST_BACKEND);
+  test_overwrite_safe   (TREXIO_FILE, TEST_BACKEND);
+  test_overwrite_unsafe (TREXIO_FILE, TEST_BACKEND);
+  test_read             (TREXIO_FILE, TEST_BACKEND);
+
+  rc = system(RM_COMMAND);
+  assert (rc == 0);
+
+  return 0;
+}
diff --git a/tests/overwrite_all_hdf5.c b/tests/overwrite_all_hdf5.c
index a623eb91..ad8d9307 100644
--- a/tests/overwrite_all_hdf5.c
+++ b/tests/overwrite_all_hdf5.c
@@ -1,266 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "overwrite_all"
+#include "test_macros.h"
+#include "overwrite_all.c"
 
-#define TEST_BACKEND 	TREXIO_HDF5
-#define TREXIO_FILE 	"test_over.h5"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE
-
-static int test_write (const char* file_name, const back_end_t backend) {
-
-/* Try to write a full set of data (num+dset_num+str+dset_str) related to benzene molecule into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  double coord[36] = {
-  0.00000000 ,  1.39250319 ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000 ,
-  1.20594314 ,  0.69625160 ,  0.00000000 ,
- -2.14171677 ,  1.23652075 ,  0.00000000 ,
- -2.14171677 , -1.23652075 ,  0.00000000 ,
-  0.00000000 , -2.47304151 ,  0.00000000 ,
-  2.14171677 , -1.23652075 ,  0.00000000 ,
-  2.14171677 ,  1.23652075 ,  0.00000000 ,
-  0.00000000 ,  2.47304151 ,  0.00000000 ,
-  };
-  const char* sym = "D6h";
-  const char* labels[] = {"C" ,
-                          "C" ,
-                          "C" ,
-                          "C" ,
-                          "C" ,
-                          "C" ,
-                          "H" ,
-                          "H" ,
-                          "H" ,
-                          "H" ,
-                          "H" ,
-                          "H" };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write the data
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_point_group(file, sym, 4);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_label(file, labels, 2);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_overwrite_unsafe (const char* file_name, const back_end_t backend) {
-
-/* Try to overwrite the data that already exists in the TREXIO file which is open in UNSAFE mode*/
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 5;
-  double coord[15] = {
-  0.00000000 ,  666.666    ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000
-  };
-  const char* sym = "Unknown";
-  const char* labels[] = {"Ru" ,
-                          "U"  ,
-                          "Cl" ,
-                          "Na" ,
-                          "H" };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'u', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written data cannot be overwritten
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_point_group(file, sym, 16);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_label(file, labels, 4);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_overwrite_safe (const char* file_name, const back_end_t backend) {
-
-/* Try to overwrite the data that already exists in the TREXIO file which is open in SAFE mode*/
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 24;
-  double coord[3] = {
-  0.00000000 ,  666.666,  0.00000000 ,
-  };
-  const char* sym = "Unknown";
-  const char* labels[] = {"Ru" ,
-                          "U"  ,
-                          "Cl" ,
-                          "Na" ,
-                          "H" };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written data cannot be overwritten
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_ATTR_ALREADY_EXISTS);
-
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_DSET_ALREADY_EXISTS);
-
-  rc = trexio_write_nucleus_point_group(file, sym, 16);
-  assert (rc == TREXIO_ATTR_ALREADY_EXISTS);
-
-  rc = trexio_write_nucleus_label(file, labels, 4);
-  assert (rc == TREXIO_DSET_ALREADY_EXISTS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int test_read(const char* file_name, const back_end_t backend) {
-
-/*========= Test read ===========*/
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  int num;
-  double* coord;
-  char** label;
-  char* point_group;
-
-/*================= START OF TEST ==================*/
-
-  // open existing file on 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read nucleus_num
-  rc = trexio_read_nucleus_num(file,&num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 5);
-
-  // read nucleus_coord
-  coord = (double*) calloc(3*num, sizeof(double));
-  rc = trexio_read_nucleus_coord(file,coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  double x = coord[1] - 666.666;
-  assert( x*x < 1.e-14);
-  free(coord);
-
-  // read nucleus_label
-  label = (char**) malloc(num*sizeof(char*));
-  for (int i=0; i<num; i++){
-    label[i] = (char*) malloc(32*sizeof(char));
-  }
-
-  rc = trexio_read_nucleus_label(file, label, 2);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp(label[0], "Ru")  == 0);
-  assert (strcmp(label[3], "Na") == 0);
-
-  for (int i=0; i<num; i++){
-    free(label[i]);
-  }
-  free(label);
-
-  point_group = (char*) malloc(32*sizeof(char));
-
-  rc = trexio_read_nucleus_point_group(file, point_group, 10);
-  assert (rc == TREXIO_SUCCESS);
-
-  char * pch;
-  pch = strtok(point_group, " ");
-  assert (strcmp(pch, "Unknown") == 0);
-  /* alternative test when 3 symbols are read from the file to point_group */
-  /*rc = trexio_read_nucleus_point_group(file, point_group, 3);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp(point_group, "B3U") == 0 );*/
-  free(point_group);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST =====================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write            (TREXIO_FILE, TEST_BACKEND);
-  test_overwrite_safe   (TREXIO_FILE, TEST_BACKEND);
-  test_overwrite_unsafe (TREXIO_FILE, TEST_BACKEND);
-  test_read             (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/overwrite_all_text.c b/tests/overwrite_all_text.c
index a8ea501d..7a10c9d4 100644
--- a/tests/overwrite_all_text.c
+++ b/tests/overwrite_all_text.c
@@ -1,266 +1,5 @@
-#include "trexio.h"
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "overwrite_all"
+#include "test_macros.h"
+#include "overwrite_all.c"
 
-#define TEST_BACKEND 	TREXIO_TEXT
-#define TREXIO_FILE 	"test_over.dir"
-#define RM_COMMAND 	"rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
-
-static int test_write (const char* file_name, const back_end_t backend) {
-
-/* Try to write a full set of data (num+dset_num+str+dset_str) related to benzene molecule into the TREXIO file */
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 12;
-  double coord[36] = {
-  0.00000000 ,  1.39250319 ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000 ,
-  1.20594314 ,  0.69625160 ,  0.00000000 ,
- -2.14171677 ,  1.23652075 ,  0.00000000 ,
- -2.14171677 , -1.23652075 ,  0.00000000 ,
-  0.00000000 , -2.47304151 ,  0.00000000 ,
-  2.14171677 , -1.23652075 ,  0.00000000 ,
-  2.14171677 ,  1.23652075 ,  0.00000000 ,
-  0.00000000 ,  2.47304151 ,  0.00000000 ,
-  };
-  const char* sym = "D6h";
-  const char* labels[] = {"C" ,
-                          "C" ,
-                          "C" ,
-                          "C" ,
-                          "C" ,
-                          "C" ,
-                          "H" ,
-                          "H" ,
-                          "H" ,
-                          "H" ,
-                          "H" ,
-                          "H" };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // write the data
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_point_group(file, sym, 4);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_label(file, labels, 2);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_overwrite_unsafe (const char* file_name, const back_end_t backend) {
-
-/* Try to overwrite the data that already exists in the TREXIO file which is open in UNSAFE mode*/
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 5;
-  double coord[15] = {
-  0.00000000 ,  666.666    ,  0.00000000 ,
- -1.20594314 ,  0.69625160 ,  0.00000000 ,
- -1.20594314 , -0.69625160 ,  0.00000000 ,
-  0.00000000 , -1.39250319 ,  0.00000000 ,
-  1.20594314 , -0.69625160 ,  0.00000000
-  };
-  const char* sym = "Unknown";
-  const char* labels[] = {"Ru" ,
-                          "U"  ,
-                          "Cl" ,
-                          "Na" ,
-                          "H" };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'u', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written data cannot be overwritten
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_point_group(file, sym, 16);
-  assert (rc == TREXIO_SUCCESS);
-
-  rc = trexio_write_nucleus_label(file, labels, 4);
-  assert (rc == TREXIO_SUCCESS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-static int test_overwrite_safe (const char* file_name, const back_end_t backend) {
-
-/* Try to overwrite the data that already exists in the TREXIO file which is open in SAFE mode*/
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  // parameters to be written
-  int num = 24;
-  double coord[3] = {
-  0.00000000 ,  666.666,  0.00000000 ,
-  };
-  const char* sym = "Unknown";
-  const char* labels[] = {"Ru" ,
-                          "U"  ,
-                          "Cl" ,
-                          "Na" ,
-                          "H" };
-
-/*================= START OF TEST ==================*/
-
-  // open file in 'write' mode
-  file = trexio_open(file_name, 'w', backend, &rc);
-  assert (file != NULL);
-
-  // check that the previously written data cannot be overwritten
-  rc = trexio_write_nucleus_num(file, num);
-  assert (rc == TREXIO_ATTR_ALREADY_EXISTS);
-
-  rc = trexio_write_nucleus_coord(file, coord);
-  assert (rc == TREXIO_DSET_ALREADY_EXISTS);
-
-  rc = trexio_write_nucleus_point_group(file, sym, 16);
-  assert (rc == TREXIO_ATTR_ALREADY_EXISTS);
-
-  rc = trexio_write_nucleus_label(file, labels, 4);
-  assert (rc == TREXIO_DSET_ALREADY_EXISTS);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST ==================*/
-
-  return 0;
-}
-
-
-int test_read(const char* file_name, const back_end_t backend) {
-
-/*========= Test read ===========*/
-
-  trexio_t* file = NULL;
-  trexio_exit_code rc;
-
-  int num;
-  double* coord;
-  char** label;
-  char* point_group;
-
-/*================= START OF TEST ==================*/
-
-  // open existing file on 'read' mode
-  file = trexio_open(file_name, 'r', backend, &rc);
-  assert (file != NULL);
-
-  // read nucleus_num
-  rc = trexio_read_nucleus_num(file,&num);
-  assert (rc == TREXIO_SUCCESS);
-  assert (num == 5);
-
-  // read nucleus_coord
-  coord = (double*) calloc(3*num, sizeof(double));
-  rc = trexio_read_nucleus_coord(file,coord);
-  assert (rc == TREXIO_SUCCESS);
-
-  double x = coord[1] - 666.666;
-  assert( x*x < 1.e-14);
-  free(coord);
-
-  // read nucleus_label
-  label = (char**) malloc(num*sizeof(char*));
-  for (int i=0; i<num; i++){
-    label[i] = (char*) malloc(32*sizeof(char));
-  }
-
-  rc = trexio_read_nucleus_label(file, label, 2);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp(label[0], "Ru")  == 0);
-  assert (strcmp(label[3], "Na") == 0);
-
-  for (int i=0; i<num; i++){
-    free(label[i]);
-  }
-  free(label);
-
-  point_group = (char*) malloc(32*sizeof(char));
-
-  rc = trexio_read_nucleus_point_group(file, point_group, 10);
-  assert (rc == TREXIO_SUCCESS);
-
-  char * pch;
-  pch = strtok(point_group, " ");
-  assert (strcmp(pch, "Unknown") == 0);
-  /* alternative test when 3 symbols are read from the file to point_group */
-  /*rc = trexio_read_nucleus_point_group(file, point_group, 3);
-  assert (rc == TREXIO_SUCCESS);
-  assert (strcmp(point_group, "B3U") == 0 );*/
-  free(point_group);
-
-  // close current session
-  rc = trexio_close(file);
-  assert (rc == TREXIO_SUCCESS);
-
-/*================= END OF TEST =====================*/
-
-  return 0;
-}
-
-
-int main(void) {
-
-/*============== Test launcher ================*/
-
-  int rc;
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  test_write            (TREXIO_FILE, TEST_BACKEND);
-  test_overwrite_safe   (TREXIO_FILE, TEST_BACKEND);
-  test_overwrite_unsafe (TREXIO_FILE, TEST_BACKEND);
-  test_read             (TREXIO_FILE, TEST_BACKEND);
-
-  rc = system(RM_COMMAND);
-  assert (rc == 0);
-
-  return 0;
-}
diff --git a/tests/template_hdf5.c b/tests/template_hdf5.c
new file mode 100644
index 00000000..6b6ca691
--- /dev/null
+++ b/tests/template_hdf5.c
@@ -0,0 +1,5 @@
+#define TEST_BACKEND_HDF5
+#define TREXIO_FILE_PREFIX "REPLACE"
+#include "test_macros.h"
+#include "REPLACE.c"
+
diff --git a/tests/template_text.c b/tests/template_text.c
new file mode 100644
index 00000000..3442f510
--- /dev/null
+++ b/tests/template_text.c
@@ -0,0 +1,5 @@
+#define TEST_BACKEND_TEXT
+#define TREXIO_FILE_PREFIX "REPLACE"
+#include "test_macros.h"
+#include "REPLACE.c"
+
diff --git a/tests/test_macros.h b/tests/test_macros.h
new file mode 100644
index 00000000..041c14fd
--- /dev/null
+++ b/tests/test_macros.h
@@ -0,0 +1,20 @@
+#include "trexio.h"
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+
+#ifdef TEST_BACKEND_HDF5
+#define TEST_BACKEND  TREXIO_HDF5
+#define TREXIO_FILE   TREXIO_FILE_PREFIX ".h5"
+#define RM_COMMAND    "rm -f -- " TREXIO_FILE
+#endif
+
+
+#ifdef TEST_BACKEND_TEXT 
+#define TEST_BACKEND  TREXIO_TEXT
+#define TREXIO_FILE   TREXIO_FILE_PREFIX ".dir"
+#define RM_COMMAND    "rm -f -- " TREXIO_FILE "/*.txt " TREXIO_FILE "/*.txt.size " TREXIO_FILE "/.lock && rm -fd -- " TREXIO_FILE
+#endif
+
+