diff --git a/.github/scripts/on-push.sh b/.github/scripts/on-push.sh
index 53dbb2250bb..a1d681e97ec 100755
--- a/.github/scripts/on-push.sh
+++ b/.github/scripts/on-push.sh
@@ -14,26 +14,25 @@ function build(){
     local BUILD_SKETCH="${SCRIPTS_DIR}/sketch_utils.sh build"
     local BUILD_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
 
-    local args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH"
+    local args="-ai $ARDUINO_IDE_PATH -au $ARDUINO_USR_PATH"
 
-    args+=" \"$fqbn\""
+    args+=" -t $target -fqbn $fqbn"
 
     if [ "$OS_IS_LINUX" == "1" ]; then
-        args+=" $target"
-        args+=" $ARDUINO_ESP32_PATH/libraries"
-        args+=" $chunk_index $chunks_cnt"
+        args+=" -p $ARDUINO_ESP32_PATH/libraries"
+        args+=" -i $chunk_index -m $chunks_cnt"
         ${BUILD_SKETCHES} ${args}
     else
-        if [ "$OS_IS_WINDOWS" == "1" ]; then
-            local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
-            local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
-            win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version
-            -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
-            args+=" ${win_opts}"
-        fi
-
         for sketch in ${sketches}; do
-            ${BUILD_SKETCH} ${args} ${sketch}
+            args+=" -s $(dirname $sketch)"
+            if [ "$OS_IS_WINDOWS" == "1" ]; then
+                local ctags_version=`ls "$ARDUINO_IDE_PATH/tools-builder/ctags/"`
+                local preprocessor_version=`ls "$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/"`
+                win_opts="-prefs=runtime.tools.ctags.path=$ARDUINO_IDE_PATH/tools-builder/ctags/$ctags_version
+                -prefs=runtime.tools.arduino-preprocessor.path=$ARDUINO_IDE_PATH/tools-builder/arduino-preprocessor/$preprocessor_version"
+                args+=" ${win_opts}"
+            fi
+            ${BUILD_SKETCH} ${args}
         done
     fi
 }
@@ -82,7 +81,7 @@ if [ "$BUILD_PIO" -eq 0 ]; then
     build "esp32s3" $FQBN_ESP32S3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32
     build "esp32s2" $FQBN_ESP32S2 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX
     build "esp32c3" $FQBN_ESP32C3 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32XX
-    build "esp32" $FQBN_ESP32 $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32
+    build "esp32"   $FQBN_ESP32   $CHUNK_INDEX $CHUNKS_CNT $SKETCHES_ESP32
 else
     source ${SCRIPTS_DIR}/install-platformio-esp32.sh
     # PlatformIO ESP32 Test
diff --git a/.github/scripts/sketch_utils.sh b/.github/scripts/sketch_utils.sh
index abe3db2b977..e3236831309 100755
--- a/.github/scripts/sketch_utils.sh
+++ b/.github/scripts/sketch_utils.sh
@@ -1,43 +1,142 @@
 #!/bin/bash
 
-function build_sketch(){ # build_sketch <ide_path> <user_path> <fqbn> <path-to-ino> [extra-options]
-    if [ "$#" -lt 4 ]; then
-        echo "ERROR: Illegal number of parameters"
-        echo "USAGE: ${0} build <ide_path> <user_path> <fqbn> <path-to-ino> [extra-options]"
-        return 1
+function build_sketch(){ # build_sketch <ide_path> <user_path> <path-to-ino> [extra-options]
+    while [ ! -z "$1" ]; do
+        case "$1" in
+        -ai )
+            shift
+            ide_path=$1
+            ;;
+        -au )
+            shift
+            user_path=$1
+            ;;
+        -t )
+            shift
+            target=$1
+            ;;
+        -fqbn )
+            shift
+            fqbn=$1
+            ;;
+        -o )
+            shift
+            options=$1
+            ;;
+        -s )
+            shift
+            sketchdir=$1
+            ;;
+        * )
+            break
+            ;;
+        esac
+        shift
+    done
+
+    xtra_opts=$*
+
+    if [ -z $sketchdir ]; then
+        echo "ERROR: Sketch directory not provided"
+        echo "$USAGE"
+        exit 1
     fi
 
-    local ide_path=$1
-    local usr_path=$2
-    local fqbn=$3
-    local sketch=$4
-    local xtra_opts=$5
-    local win_opts=$6
+    # No FQBN was passed, try to get it from other options
+
+    if [ -z $fqbn ]; then
+        if [ -z $target ]; then
+            echo "ERROR: Unspecified chip"
+            echo "$USAGE"
+            exit 1
+        fi
+
+        # The options are either stored in the test directory, for a per test
+        # customization or passed as parameters.  Command line options take
+        # precedence.  Note that the following logic also falls to the default
+        # parameters if no arguments were passed and no file was found.
+
+        if [ -z $options ] && [ -f $sketchdir/cfg.json ]; then
+            # The config file could contain multiple FQBNs for one chip.  If
+            # that's the case we build one time for every FQBN.
+
+            len=`jq -r --arg chip $target '.targets[] | select(.name==$chip) | .fqbn | length' $sketchdir/cfg.json`
+            fqbn=`jq -r --arg chip $target '.targets[] | select(.name==$chip) | .fqbn' $sketchdir/cfg.json`
+        else
+            # Since we are passing options, we will end up with only one FQBN to
+            # build.
+
+            len=1
+
+            # Default FQBN options if none were passed in the command line.
+
+            esp32_opts="PSRAM=enabled,PartitionScheme=huge_app"
+            esp32s2_opts="PSRAM=enabled,PartitionScheme=huge_app"
+            esp32s3_opts="PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
+            esp32c3_opts="PartitionScheme=huge_app"
+
+            # Select the common part of the FQBN based on the target.  The rest will be
+            # appended depending on the passed options.
+
+            case "$target" in
+                "esp32")
+                    fqbn="espressif:esp32:esp32:${options:-$esp32_opts}"
+                ;;
+                "esp32s2")
+                    fqbn="espressif:esp32:esp32s2:${options:-$esp32s2_opts}"
+                ;;
+                "esp32c3")
+                    fqbn="espressif:esp32:esp32c3:${options:-$esp32c3_opts}"
+                ;;
+                "esp32s3")
+                    fqbn="espressif:esp32:esp32s3:${options:-$esp32s3_opts}"
+                ;;
+            esac
+
+            # Make it look like a JSON array.
+
+            fqbn="[\"$fqbn\"]"
+        fi
+    else
+        # An FQBN was passed.  Make it look like a JSON array.
+
+        len=1
+        fqbn="[\"$fqbn\"]"
+    fi
+
+    if [ -z "$fqbn" ]; then
+        echo "No FQBN passed or unvalid chip: $target"
+        exit 1
+    fi
 
     ARDUINO_CACHE_DIR="$HOME/.arduino/cache.tmp"
     if [ -z "$ARDUINO_BUILD_DIR" ]; then
-        build_dir="$(dirname $sketch)/build"
+        build_dir="$sketchdir/build"
     else
         build_dir="$ARDUINO_BUILD_DIR"
     fi
 
-    echo $sketch
-
-    rm -rf "$build_dir"
-    mkdir -p "$build_dir"
     mkdir -p "$ARDUINO_CACHE_DIR"
-    $ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \
-        -fqbn=$fqbn \
-        -warnings="all" \
-        -tools "$ide_path/tools-builder" \
-        -tools "$ide_path/tools" \
-        -built-in-libraries "$ide_path/libraries" \
-        -hardware "$ide_path/hardware" \
-        -hardware "$usr_path/hardware" \
-        -libraries "$usr_path/libraries" \
-        -build-cache "$ARDUINO_CACHE_DIR" \
-        -build-path "$build_dir" \
-        $win_opts $xtra_opts "$sketch"
+    for i in `seq 0 $(($len - 1))`
+    do
+        rm -rf "$build_dir$i"
+        mkdir -p "$build_dir$i"
+        currfqbn=`echo $fqbn | jq -r --argjson i $i '.[$i]'`
+        sketchname=$(basename $sketchdir)
+        echo "Building $sketchname with FQBN=$currfqbn"
+        $ide_path/arduino-builder -compile -logger=human -core-api-version=10810 \
+            -fqbn=\"$currfqbn\" \
+            -warnings="all" \
+            -tools "$ide_path/tools-builder" \
+            -tools "$ide_path/tools" \
+            -built-in-libraries "$ide_path/libraries" \
+            -hardware "$ide_path/hardware" \
+            -hardware "$user_path/hardware" \
+            -libraries "$user_path/libraries" \
+            -build-cache "$ARDUINO_CACHE_DIR" \
+            -build-path "$build_dir$i" \
+            $xtra_opts "${sketchdir}/${sketchname}.ino"
+    done
 }
 
 function count_sketches(){ # count_sketches <path> [target]
@@ -73,29 +172,63 @@ function count_sketches(){ # count_sketches <path> [target]
     return $sketchnum
 }
 
-function build_sketches(){ # build_sketches <ide_path> <user_path> <fqbn> <target> <path> <chunk> <total-chunks> [extra-options]
-    local ide_path=$1
-    local usr_path=$2
-    local fqbn=$3
-    local target=$4
-    local path=$5
-    local chunk_idex=$6
-    local chunks_num=$7
-    local xtra_opts=$8
-
-    if [ "$#" -lt 7 ]; then
-        echo "ERROR: Illegal number of parameters"
-        echo "USAGE: ${0} chunk_build <ide_path> <user_path> <fqbn> <target> <path> [<chunk> <total-chunks>] [extra-options]"
-        return 1
+function build_sketches(){ # build_sketches <ide_path> <user_path> <target> <path> <chunk> <total-chunks> [extra-options]
+
+    local args=""
+    while [ ! -z "$1" ]; do
+        case $1 in
+        -ai )
+            shift
+            ide_path=$1
+            ;;
+        -au )
+            shift
+            user_path=$1
+            ;;
+        -t )
+            shift
+            target=$1
+            args+=" -t $target"
+            ;;
+        -fqbn )
+            shift
+            fqbn=$1
+            args+=" -fqbn $fqbn"
+            ;;
+        -p )
+            shift
+            path=$1
+            ;;
+        -i )
+            shift
+            chunk_index=$1
+            ;;
+        -m )
+            shift
+            chunk_max=$1
+            ;;
+        * )
+            break
+            ;;
+        esac
+        shift
+    done
+
+    local xtra_opts=$*
+
+    if [ -z $chunk_index ] || [ -z $chunk_max ]; then
+        echo "ERROR: Invalid chunk paramters"
+        echo "$USAGE"
+        exit 1
     fi
 
-    if [ "$chunks_num" -le 0 ]; then
+    if [ "$chunk_max" -le 0 ]; then
         echo "ERROR: Chunks count must be positive number"
         return 1
     fi
-    if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
-        echo "ERROR: Chunk index must be less than chunks count"
-        return 1
+
+    if [ "$chunk_index" -gt "$chunk_max" ] &&  [ "$chunk_max" -ge 2 ]; then
+        chunk_index=$chunk_max
     fi
 
     set +e
@@ -105,25 +238,25 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <fqbn> <targe
     local sketches=$(cat sketches.txt)
     rm -rf sketches.txt
 
-    local chunk_size=$(( $sketchcount / $chunks_num ))
-    local all_chunks=$(( $chunks_num * $chunk_size ))
+    local chunk_size=$(( $sketchcount / $chunk_max ))
+    local all_chunks=$(( $chunk_max * $chunk_size ))
     if [ "$all_chunks" -lt "$sketchcount" ]; then
         chunk_size=$(( $chunk_size + 1 ))
     fi
 
     local start_index=0
     local end_index=0
-    if [ "$chunk_idex" -ge "$chunks_num" ]; then
-        start_index=$chunk_idex
+    if [ "$chunk_index" -ge "$chunk_max" ]; then
+        start_index=$chunk_index
         end_index=$sketchcount
     else
-        start_index=$(( $chunk_idex * $chunk_size ))
+        start_index=$(( $chunk_index * $chunk_size ))
         if [ "$sketchcount" -le "$start_index" ]; then
             echo "Skipping job"
             return 0
         fi
 
-        end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
+        end_index=$(( $(( $chunk_index + 1 )) * $chunk_size ))
         if [ "$end_index" -gt "$sketchcount" ]; then
             end_index=$sketchcount
         fi
@@ -131,17 +264,17 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <fqbn> <targe
 
     local start_num=$(( $start_index + 1 ))
     echo "Found $sketchcount Sketches for target '$target'";
-    echo "Chunk Index : $chunk_idex"
-    echo "Chunk Count : $chunks_num"
+    echo "Chunk Index : $chunk_index"
+    echo "Chunk Count : $chunk_max"
     echo "Chunk Size  : $chunk_size"
     echo "Start Sketch: $start_num"
     echo "End Sketch  : $end_index"
 
     local sketchnum=0
+    args+=" -ai $ide_path -au $user_path"
     for sketch in $sketches; do
         local sketchdir=$(dirname $sketch)
         local sketchdirname=$(basename $sketchdir)
-        local sketchname=$(basename $sketch)
         sketchnum=$(($sketchnum + 1))
         if [ "$sketchnum" -le "$start_index" ] \
         || [ "$sketchnum" -gt "$end_index" ]; then
@@ -149,7 +282,8 @@ function build_sketches(){ # build_sketches <ide_path> <user_path> <fqbn> <targe
         fi
         echo ""
         echo "Building Sketch Index $(($sketchnum - 1)) - $sketchdirname"
-        build_sketch "$ide_path" "$usr_path" "$fqbn" "$sketch" "$xtra_opts"
+        args+=" -s $sketchdir $xtra_opts"
+        build_sketch $args
         local result=$?
         if [ $result -ne 0 ]; then
             return $result
@@ -169,24 +303,21 @@ Available commands:
 cmd=$1
 shift
 if [ -z $cmd ]; then
-  echo "ERROR: No command supplied"
-  echo "$USAGE"
-  exit 2
+    echo "ERROR: No command supplied"
+    echo "$USAGE"
+    exit 2
 fi
 
 case "$cmd" in
-  "count")
-    count_sketches $*
+    "count") count_sketches $*
     ;;
-  "build")
-    build_sketch $*
+    "build") build_sketch $*
     ;;
-  "chunk_build")
-    build_sketches $*
+    "chunk_build") build_sketches $*
     ;;
-  *)
-    echo "ERROR: Unrecognized command"
-    echo "$USAGE"
-    exit 2
+    *)
+        echo "ERROR: Unrecognized command"
+        echo "$USAGE"
+        exit 2
 esac
 
diff --git a/.github/scripts/tests_build.sh b/.github/scripts/tests_build.sh
index fd0d2db2d2f..f7e4b7aaed2 100755
--- a/.github/scripts/tests_build.sh
+++ b/.github/scripts/tests_build.sh
@@ -1,58 +1,63 @@
 #!/bin/bash
 
+USAGE="
+USAGE:
+    ${0} -c <chunk_build_opts>
+       Example: ${0} -c -t esp32 -i 0 -m 15
+    ${0} -s sketch_name <build_opts>
+       Example: ${0} -s hello_world -t esp32
+    ${0} -clean
+       Remove build and test generated files
+"
+
+function clean(){
+    rm -rf tests/*/build*/
+    rm -rf tests/.pytest_cache
+    rm -rf tests/*/__pycache__/
+    rm -rf tests/*/*.xml
+}
+
 SCRIPTS_DIR="./.github/scripts"
 BUILD_CMD=""
 
-if [ $# -eq 3 ]; then
-    chunk_build=1
-elif [ $# -eq 2 ]; then
-    chunk_build=0
-else
-  echo "ERROR: Illegal number of parameters"
-  echo "USAGE:
-        ${0} <target> <sketch_dir>
-        ${0} <target> <chunk> <total_chunks>
-        "
-  exit 0
-fi
-
-target=$1
-
-case "$target" in
-    "esp32") fqbn="espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app"
-    ;;
-    "esp32s2") fqbn="espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"
-    ;;
-    "esp32c3") fqbn="espressif:esp32:esp32c3:PartitionScheme=huge_app"
-    ;;
-    "esp32s3") fqbn="espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"
-    ;;
-esac
-
-if [ -z $fqbn ]; then
-  echo "Unvalid chip $1"
-  exit 0
-fi
+chunk_build=0
+
+while [ ! -z "$1" ]; do
+    case $1 in
+    -c )
+        chunk_build=1
+        ;;
+    -s )
+        shift
+        sketch=$1
+        ;;
+    -h )
+        echo "$USAGE"
+        exit 0
+        ;;
+    -clean )
+        clean
+        exit 0
+        ;;
+    * )
+      break
+      ;;
+    esac
+    shift
+done
 
 source ${SCRIPTS_DIR}/install-arduino-ide.sh
 source ${SCRIPTS_DIR}/install-arduino-core-esp32.sh
 
-args="$ARDUINO_IDE_PATH $ARDUINO_USR_PATH \"$fqbn\""
+args="-ai $ARDUINO_IDE_PATH -au $ARDUINO_USR_PATH"
 
 if [ $chunk_build -eq 1 ]; then
-    chunk_index=$2
-    chunk_max=$3
-
-    if [ "$chunk_index" -gt "$chunk_max" ] &&  [ "$chunk_max" -ge 2 ]; then
-        chunk_index=$chunk_max
-    fi
     BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh chunk_build"
-    args+=" $target $PWD/tests $chunk_index $chunk_max"
+    args+=" -p $PWD/tests"
 else
-    sketchdir=$2
     BUILD_CMD="${SCRIPTS_DIR}/sketch_utils.sh build"
-    args+=" $PWD/tests/$sketchdir/$sketchdir.ino"
+    args+=" -s $PWD/tests/$sketch"
 fi
 
-${BUILD_CMD} ${args}
+${BUILD_CMD} ${args} $*
 
diff --git a/.github/scripts/tests_run.sh b/.github/scripts/tests_run.sh
index a13f3c00c1d..94626de9c46 100755
--- a/.github/scripts/tests_run.sh
+++ b/.github/scripts/tests_run.sh
@@ -1,71 +1,138 @@
 #!/bin/bash
 
-target=$1
-chunk_idex=$2
-chunks_num=$3
+function run_test() {
+    local target=$1
+    local sketch=$2
+    local options=$3
+    local erase_flash=$4
+    local sketchdir=$(dirname $sketch)
+    local sketchname=$(basename $sketchdir)
+
+    if [ $options -eq 0 ] && [ -f $sketchdir/cfg.json ]; then
+        len=`jq -r --arg chip $target '.targets[] | select(.name==$chip) | .fqbn | length' $sketchdir/cfg.json`
+    else
+        len=1
+    fi
+
+    for i in `seq 0 $(($len - 1))`
+    do
+        echo "Running test: $sketchname -- Config: $i"
+        if [ $erase_flash -eq 1 ]; then
+            esptool.py -c $target erase_flash
+        fi
+
+        pytest tests --build-dir tests/$sketchname/build$i -k test_$sketchname --junit-xml=tests/$sketchname/$sketchname$i.xml
+        result=$?
+        if [ $result -ne 0 ]; then
+            return $result
+        fi
+    done
+}
 
 SCRIPTS_DIR="./.github/scripts"
 COUNT_SKETCHES="${SCRIPTS_DIR}/sketch_utils.sh count"
 
-source ${SCRIPTS_DIR}/install-arduino-ide.sh
+chunk_run=0
+options=0
+erase=0
 
-if [ "$chunks_num" -le 0 ]; then
-    echo "ERROR: Chunks count must be positive number"
-    return 1
-fi
-if [ "$chunk_idex" -ge "$chunks_num" ] && [ "$chunks_num" -ge 2 ]; then
-    echo "ERROR: Chunk index must be less than chunks count"
-    return 1
-fi
+while [ ! -z "$1" ]; do
+    case $1 in
+    -c )
+        chunk_run=1
+        ;;
+    -o )
+        options=1
+        ;;
+    -s )
+        shift
+        sketch=$1
+        ;;
+    -t )
+        shift
+        target=$1
+        ;;
+    -i )
+        shift
+        chunk_index=$1
+        ;;
+    -m )
+        shift
+        chunk_max=$1
+        ;;
+    -e )
+        erase=1
+        ;;
+    -h )
+        echo "$USAGE"
+        exit 0
+        ;;
+    * )
+      break
+      ;;
+    esac
+    shift
+done
 
-set +e
-${COUNT_SKETCHES} $PWD/tests $target
-sketchcount=$?
-set -e
-sketches=$(cat sketches.txt)
-rm -rf sketches.txt
-
-chunk_size=$(( $sketchcount / $chunks_num ))
-all_chunks=$(( $chunks_num * $chunk_size ))
-if [ "$all_chunks" -lt "$sketchcount" ]; then
-    chunk_size=$(( $chunk_size + 1 ))
-fi
+source ${SCRIPTS_DIR}/install-arduino-ide.sh
 
-start_index=0
-end_index=0
-if [ "$chunk_idex" -ge "$chunks_num" ]; then
-    start_index=$chunk_idex
-    end_index=$sketchcount
+if [ $chunk_run -eq 0 ]; then
+    run_test $target $PWD/tests/$sketch/$sketch.ino $options $erase
 else
-    start_index=$(( $chunk_idex * $chunk_size ))
-    if [ "$sketchcount" -le "$start_index" ]; then
-        echo "Skipping job"
-        return 0
-    fi
+  if [ "$chunk_max" -le 0 ]; then
+      echo "ERROR: Chunks count must be positive number"
+      return 1
+  fi
 
-    end_index=$(( $(( $chunk_idex + 1 )) * $chunk_size ))
-    if [ "$end_index" -gt "$sketchcount" ]; then
-        end_index=$sketchcount
-    fi
-fi
+  if [ "$chunk_index" -ge "$chunk_max" ] && [ "$chunk_max" -ge 2 ]; then
+      echo "ERROR: Chunk index must be less than chunks count"
+      return 1
+  fi
 
-start_num=$(( $start_index + 1 ))
-sketchnum=0
-
-for sketch in $sketches; do
-    sketchdir=$(dirname $sketch)
-    sketchdirname=$(basename $sketchdir)
-    sketchname=$(basename $sketch)
-    sketchnum=$(($sketchnum + 1))
-    if [ "$sketchnum" -le "$start_index" ] \
-    || [ "$sketchnum" -gt "$end_index" ]; then
-        continue
-    fi
-    echo ""
-    echo "Test for Sketch Index $(($sketchnum - 1)) - $sketchdirname"
-    pytest tests -k test_$sketchdirname --junit-xml=tests/$sketchdirname/$sketchdirname.xml
-    result=$?
-    if [ $result -ne 0 ]; then
-        return $result
-    fi
-done
+  set +e
+  ${COUNT_SKETCHES} $PWD/tests $target
+  sketchcount=$?
+  set -e
+  sketches=$(cat sketches.txt)
+  rm -rf sketches.txt
+
+  chunk_size=$(( $sketchcount / $chunk_max ))
+  all_chunks=$(( $chunk_max * $chunk_size ))
+  if [ "$all_chunks" -lt "$sketchcount" ]; then
+      chunk_size=$(( $chunk_size + 1 ))
+  fi
+
+  start_index=0
+  end_index=0
+  if [ "$chunk_index" -ge "$chunk_max" ]; then
+      start_index=$chunk_index
+      end_index=$sketchcount
+  else
+      start_index=$(( $chunk_index * $chunk_size ))
+      if [ "$sketchcount" -le "$start_index" ]; then
+          echo "Skipping job"
+          return 0
+      fi
+
+      end_index=$(( $(( $chunk_index + 1 )) * $chunk_size ))
+      if [ "$end_index" -gt "$sketchcount" ]; then
+          end_index=$sketchcount
+      fi
+  fi
+
+  start_num=$(( $start_index + 1 ))
+  sketchnum=0
+
+  for sketch in $sketches; do
+
+      sketchnum=$(($sketchnum + 1))
+      if [ "$sketchnum" -le "$start_index" ] \
+      || [ "$sketchnum" -gt "$end_index" ]; then
+          continue
+      fi
+      echo ""
+      echo "Sketch Index $(($sketchnum - 1))"
+
+      run_test $target $sketch $options $erase
+  done
+fi
diff --git a/.github/workflows/hil.yml b/.github/workflows/hil.yml
index b63223d2542..600e932d82f 100644
--- a/.github/workflows/hil.yml
+++ b/.github/workflows/hil.yml
@@ -31,14 +31,14 @@ jobs:
         id: gen-chunks
         run: |
           set +e
-          bash .github/scripts/sketch_utils.sh count tests
-          sketches=$((? - 1))
-          if [[ $sketches -gt ${{env.MAX_CHUNKS}} ]]; then
+          .github/scripts/sketch_utils.sh count tests
+          sketches=$?
+          if [[ $sketches -ge ${{env.MAX_CHUNKS}} ]]; then
             $sketches=${{env.MAX_CHUNKS}}
           fi
           set -e
           rm sketches.txt
-          CHUNKS=$(jq -c -n '$ARGS.positional' --args `seq 0 1 $sketches`)
+          CHUNKS=$(jq -c -n '$ARGS.positional' --args `seq 0 1 $((sketches - 1))`)
           echo "::set-output name=chunks::${CHUNKS}"
 
   Build:
@@ -56,14 +56,14 @@ jobs:
 
       - name: Build sketches
         run: |
-          bash .github/scripts/tests_build.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
+          bash .github/scripts/tests_build.sh -c -t ${{matrix.chip}} -i ${{matrix.chunks}} -m ${{env.MAX_CHUNKS}}
       - name: Upload ${{matrix.chip}}-${{matrix.chunks}} artifacts
         uses: actions/upload-artifact@v2
         with:
           name: ${{matrix.chip}}-${{matrix.chunks}}.artifacts
           path: |
-             tests/*/build/*.bin
-             tests/*/build/*.json
+             tests/*/build*/*.bin
+             tests/*/build*/*.json
   Test:
     needs: [gen_chunks, Build]
     name: ${{matrix.chip}}-Test#${{matrix.chunks}}
@@ -96,10 +96,11 @@ jobs:
          run: |
            pip install -U pip
            pip install -r tests/requirements.txt
+           apt update && apt install -y -qq jq
 
        - name: Run Tests
          run: |
-           bash .github/scripts/tests_run.sh ${{matrix.chip}} ${{matrix.chunks}} ${{env.MAX_CHUNKS}}
+           bash .github/scripts/tests_run.sh -c -t ${{matrix.chip}} -i ${{matrix.chunks}} -m ${{env.MAX_CHUNKS}} -e
 
        - name: Upload test result artifacts
          uses: actions/upload-artifact@v2
diff --git a/tests/.gitignore b/tests/.gitignore
index 3d433392930..d9333804a5c 100644
--- a/tests/.gitignore
+++ b/tests/.gitignore
@@ -1,2 +1,3 @@
-build/
+build*/
 __pycache__/
+*.xml
diff --git a/tests/democfg/cfg.json b/tests/democfg/cfg.json
new file mode 100644
index 00000000000..2b9f26bf1fe
--- /dev/null
+++ b/tests/democfg/cfg.json
@@ -0,0 +1,24 @@
+{
+  "targets": [
+    {
+      "name": "esp32",
+      "fqbn":[
+        "espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app,FlashMode=dio",
+        "espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app,FlashMode=dout",
+        "espressif:esp32:esp32:PSRAM=enabled,PartitionScheme=huge_app,FlashMode=qio"
+      ]
+    },
+    {
+      "name": "esp32s2",
+      "fqbn": ["espressif:esp32:esp32s2:PSRAM=enabled,PartitionScheme=huge_app"]
+    },
+    {
+      "name": "esp32c3",
+      "fqbn": ["espressif:esp32:esp32c3:PartitionScheme=huge_app"]
+    },
+    {
+      "name": "esp32s3",
+      "fqbn": ["espressif:esp32:esp32s3:PSRAM=opi,USBMode=default,PartitionScheme=huge_app"]
+    }
+  ]
+}
diff --git a/tests/democfg/democfg.ino b/tests/democfg/democfg.ino
new file mode 100644
index 00000000000..835dc1b20b2
--- /dev/null
+++ b/tests/democfg/democfg.ino
@@ -0,0 +1,11 @@
+void setup(){
+  Serial.begin(115200);
+  while (!Serial) {
+    ;
+  }
+
+  Serial.println("Hello cfg!");
+}
+
+void loop(){
+}
diff --git a/tests/democfg/test_democfg.py b/tests/democfg/test_democfg.py
new file mode 100644
index 00000000000..0dcc877dc36
--- /dev/null
+++ b/tests/democfg/test_democfg.py
@@ -0,0 +1,2 @@
+def test_cfg(dut):
+    dut.expect('Hello cfg!')