3

I have a folder filled with 9 Robot Framework test files. Only 8 of them have to be executed, as the last one is used to set up all the others (let's call it config.robot).

If I had to run all those tests I would have done something like

for test_file in folder/*.robot; do
    robot -b debug.log -d log/ $test_file.robot;
done

but in this case it means that config.robot will also be run, which I don't want.

How could I perform a for loop on all files in folder except one?

If that helps, all files except config.robot respect the following naming syntax: they all start with their execution order and are followed by their actual name, e.g. 01__init-connection.robot.


Edit: Before posting that question I had already seen and tried the answers offered in Exclude one pattern from glob match and wrote something similar to

shopt -s extglob
for test_file in folder/!(config).robot; do ...

But Robot Framework does not recognize the file name:

Parsing 'folder/!(config).robot' failed: Data source does not exist.

so I guess that Robot Framework doesn't like that syntax.
I'm thinking about setting a variable with the results of a find according to a regex matching my filename structure and then performing the for loop on the variable:

SUITES=$(find . -regex '^[0-9][0-9][a-zA-Z_-]*')
for SUITE in $SUITES; do robot -b ...

But for some reason when I echo SUITES it returns nothing. I don't know what I missed here.

avazula
  • 131
  • 1
    @avazula, if you get the pattern literally back from a glob, it means the pattern didn't match anything (and you didn't have nullglob or failglob set). You may want to check the exact commands you run and the files you have to see that they actually match. E.g. try what touch foo.robot bar.robot config.robot; shopt -s extglob; for f in ./!(config).robot; do echo "file: $f"; done does in an empty directory, it should print the names of foo.robot and bar.robot. – ilkkachu Jan 29 '19 at 18:21
  • GNU find has its peculiar approach to regular expressions. It supports several regex types, defaulting to emacs. Also, note that find regular expressions must match whole paths, not just file names. For instance, if you are familiar with BRE, and assuming your files are in ./folder (relative to the current directory), you may use find . -regextype posix-basic -regex '\./folder/[0-9]\{2\}[-A-Za-z_]\{1,\}\.robot'. Nevertheless, this approach is really fragile and not advisable. Getting globbing right is the way to go. – fra-san Jan 29 '19 at 18:53
  • Regarding you edit: You tagged the question with [tag:bash]. If this is not what your framework thingy uses, then please figure out what shell it uses and re-tag the question appropriately. Jeff's answer is correct for bash. – Kusalananda Jan 29 '19 at 19:42
  • Any other shell than Bash would probably not have shopt, and the parenthesis in the glob would likely be a syntax error if extended globs weren't supported. (Except that it seems a valid glob in Zsh, but then Zsh would by default complain about a glob that didn't match anything so there wouldn't be an error from robot.) – ilkkachu Jan 29 '19 at 20:04
  • @avazula, I just saw your updated post -- 8 months later! -- and updated my answer to help explain why you had those results. – Jeff Schaller Aug 29 '19 at 14:04

3 Answers3

5

In bash, as tagged:

shopt -s extglob
for test_file in folder/!(config).robot; do robot -b debug.log -d log/ "$test_file".robot; done

In response to the update:

shopt -s extglob
for test_file in folder/!(config).robot; do ...

resulting in:

Parsing 'folder/!(config).robot' failed: Data source does not exist.

This could happen if there are no ".robot" files in "folder" besides "config.robot". Consider:

$ mkdir folder
$ touch folder/config.robot
$ shopt -s extglob
$ shopt -u nullglob
$ for f in folder/!(config).robot; do ls --- "$f"; done
ls: cannot access folder/!(config).robot: No such file or directory

Versus (a fresh start):

$ mkdir folder
$ touch folder/config.robot
$ shopt -s extglob
$ shopt -s nullglob
$ for f in folder/!(config).robot; do ls -- "$f"; done
$

Where the for loop does not execute any commands because the wildcard did not expand to any files.

Or the alternative, where there are non-config.robot files there:

$ mkdir folder
$ touch folder/config.robot
$ touch folder/01__init-connection.robot
$ shopt -s extglob
$ shopt -s nullglob
$ for f in folder/!(config).robot; do ls -- "$f"; done
folder/01__init-connection.robot
Jeff Schaller
  • 67,283
  • 35
  • 116
  • 255
2

You can use the continue command.

Also note that the variable picks up the whole path.

for f in folder/*.robot; do
    test "$f" = folder/config.robot && continue 
    robot -b debug.log -d log/ "$f"
done
1

Try this,

for test_file in folder/*.robot; 
do 
    [ "$test_file" != "config.robot" ] && robot -b debug.log -d log/ $test_file.robot;
done
  • robot will run only if $test_file is not equal to config.robot

or simple using find

find folder/*.robot ! -name "config.robot" -exec robot -b debug.log -d log/ {} +
ilkkachu
  • 138,973
Siva
  • 9,077
  • Using extglob (as in @sparhawk comment) is more efficient... – xenoid Jan 29 '19 at 10:57
  • @xenoid, efficient in what way? If you mean in terms of CPU time used, the difference is quite likely to be totally negligible. If you mean in terms of readability or such, do note that not everyone might be familiar with ksh-style extended globs, and they're not standard anyway, unlike the if solution – ilkkachu Jan 29 '19 at 18:23
  • find folder/*.robot ... works but is a bit odd. You'd usually use find . -name "*.robot" ! -name "config.robot" -exec ... Of course, the latter would recurse to subdirectories, and would not keep the filenames in numerical order, while the former does exactly the opposite... – ilkkachu Jan 29 '19 at 18:27
  • Fewer processes and shorter code. "Not everyone can be familiar...": yes, but everyone can/should learn a new trick from time to time otherwise we would still all be using the original sh. My skills improve because when I see some code I don't recognize, I try to understand where that comes from and if I can use it myself. – xenoid Jan 29 '19 at 23:48