How do I set up a multi-file project in the Arduino IDE?
You have two options with ArduinoIDE. 

First Each module in a module directory 

So the structure looks like

  main_routine
     main_routine.ino
  --module1
      module1.ino  #test routine  
      module1.cpp
      module1.h   
 --module2
  .....


included in main_routine.ino

   #include "module1/module1.h"
   #include "module2/module2.h"


So you have everything in your master dir and in module specific subdirs below - Nothing is or will be copied by the ArduinoIDE (v1.8.12)

The second (more hacky way) is to have everything in one dir and for development testing working with include guards in the main_routine.ino

 // for production comment all MODULEX_TEST and uncomment PRODUCTION
 //#define PRODUCTION
 #define MODULE1_TEST 
 //#define MODULE2_TEST
.....
#if defined (PRODUCTION) || defined (MODULE1_TEST )
   #include "module1/module1.h"
#endif

#if defined (PRODUCTION) || defined (MODULE1_TEST )
   uint8_t myModule1Var = 0;
#endif

setup(){
.....
#if defined (PRODUCTION) || defined (MODULE1_TEST )
   myModule1setup someInit(1,2,3);
#endif
.....
 }

loop(){
.....
#if defined (PRODUCTION) || defined (MODULE1_TEST )
   void mymodule1Func(){....};
#endif 
#ifdef MODULE1_TEST
   void mymodule1Test(){....};
#endif 


Pros and cons


+This approach gives you the possibility to test two modules together. 
-Its harder to read, but 
+easier to document with tools like doxygen
~Only the active includes are compiled and so no overhead in the compiled code


Be aware that with some tool chains there are at the moment problems when using special templates (works if everything is in one module file - I use an "extended header" file as momentary work around) or arrays as initializer (open issue in esp8266)