cucumber_statistics 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,91 @@
1
+ module CucumberStatistics
2
+ class StepStatistics
3
+ def initialize
4
+ @all = Hash.new
5
+ end
6
+
7
+ def record step_name, duration, file_colon_line
8
+
9
+ # "/Users/kross/alienfast/acme/features/account management/admin_cancel_account.feature:8"
10
+ step_results = @all[step_name]
11
+ step_results ||= Hash.new
12
+ step_results[:instances] ||= []
13
+ step_results[:instances] << duration
14
+ begin
15
+ file = file_colon_line[file_colon_line.index('features')..-1]
16
+ step_results[:file] = file
17
+ rescue Exception => e
18
+ step_results[:file] = e.message
19
+ end
20
+
21
+ @all[step_name] ||= step_results
22
+ end
23
+
24
+ def calculate
25
+ @all.each do |step_name, step_results|
26
+ step_results[:total] = step_results[:instances].inject{|sum,x| sum + x }
27
+ step_results[:count] = step_results[:instances].count
28
+ step_results[:average] = step_results[:total].to_f / step_results[:count].to_f
29
+ step_results[:fastest] = step_results[:instances].sort.first
30
+ step_results[:slowest] = step_results[:instances].sort.last
31
+ step_results[:variation] = step_results[:slowest] - step_results[:fastest]
32
+ step_results[:variance] = self.sample_variance step_results[:instances]
33
+ step_results[:standard_deviation] = self.standard_deviation step_results[:variance]
34
+ end
35
+ end
36
+
37
+ def all
38
+ @all
39
+ end
40
+
41
+ def sort_by_property property
42
+ result = @all.sort {|a,b| a.last[property.to_sym] <=> b.last[property.to_sym]}
43
+ result
44
+ end
45
+
46
+ def highest_average
47
+ sort_by_property(:average).reverse.first
48
+ end
49
+
50
+ def highest_total
51
+ sort_by_property(:total).reverse.first
52
+ end
53
+
54
+ def highest_variation
55
+ sort_by_property(:variation).reverse.first
56
+ end
57
+
58
+ def average_times_plot_data
59
+ @all.map {|step_name, data| data[:average].to_f}.sort.reverse
60
+ end
61
+
62
+ def total_times_plot_data
63
+ sort_by_property(:average).reverse.map {|step_name, data| data[:total].to_f}
64
+ end
65
+
66
+ def step_part_of_total
67
+ @all.map {|step_name, data| data[:total]}.sort.reverse
68
+ end
69
+
70
+ def total_elapsed_time
71
+ @all.map {|step_name, data| data[:total]}.inject{|sum,x| sum + x }
72
+ end
73
+
74
+ def sample_variance data
75
+ count = data.count
76
+ average = data.inject{|sum,x| sum + x } / count.to_f
77
+
78
+ return nil if count <= 1
79
+
80
+ sum = data.inject(0){|acc,i|acc.to_f + (i.to_f - average)**2.0}
81
+
82
+ return 1 / (count.to_f - 1.0) * sum.to_f
83
+ end
84
+
85
+ def standard_deviation sample_variance
86
+ return nil if sample_variance.nil?
87
+
88
+ return Math.sqrt(sample_variance)
89
+ end
90
+ end
91
+ end
@@ -0,0 +1,18 @@
1
+ module CucumberStatistics
2
+ class UnusedSteps
3
+ def initialize
4
+ @all = Hash.new
5
+ end
6
+
7
+ def record step_name, where
8
+ result = @all[step_name]
9
+ result = where
10
+
11
+ @all[step_name] ||= result
12
+ end
13
+
14
+ def all
15
+ @all
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,3 @@
1
+ module CucumberStatistics
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,162 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en">
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <meta http-equiv="X-UA-Compatible" content="IE=edge">
6
+ <meta name="viewport" content="width=device-width, initial-scale=1">
7
+ <meta name="description" content="Cucumber Step Statistics">
8
+ <meta name="author" content="AlienFast">
9
+
10
+ <title>Cucumber Step Statistics</title>
11
+
12
+ <!-- Bootstrap core CSS -->
13
+ <link href="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css" rel="stylesheet">
14
+
15
+ <!-- Custom styles for this layout -->
16
+ <style type="text/css">
17
+ body {
18
+ min-height: 2000px;
19
+ padding-top: 70px;
20
+ }
21
+
22
+ td {
23
+ white-space: nowrap;
24
+ /*max-width: 100px;*/
25
+ }
26
+ tr td:first-child {
27
+ overflow: hidden;
28
+ text-overflow: ellipsis;
29
+ max-width: 300px;
30
+ }
31
+ </style>
32
+
33
+ <link href="https://raw.githack.com/drvic10k/bootstrap-sortable/master/Contents/bootstrap-sortable.css" rel="stylesheet">
34
+ <!-- HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries -->
35
+ <!--[if lt IE 9]>
36
+ <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
37
+ <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
38
+ <![endif]-->
39
+ </head>
40
+
41
+ <body>
42
+
43
+ <!-- Fixed navbar -->
44
+ <div class="navbar navbar-default navbar-fixed-top" role="navigation">
45
+ <div class="container">
46
+ <div class="navbar-header">
47
+ <button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbar-collapse">
48
+ <span class="sr-only">Toggle navigation</span>
49
+ <span class="icon-bar"></span>
50
+ <span class="icon-bar"></span>
51
+ <span class="icon-bar"></span>
52
+ </button>
53
+ <a class="navbar-brand" href="#">cucumber_statistics</a>
54
+ </div>
55
+ <div class="navbar-collapse collapse">
56
+ <ul class="nav navbar-nav">
57
+ <li class="active"><a href="#">Home</a></li>
58
+ <li><a href="#about">About</a></li>
59
+ <li><a href="#contact">Contact</a></li>
60
+ <li class="dropdown">
61
+ <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>
62
+ <ul class="dropdown-menu">
63
+ <li><a href="#">Action</a></li>
64
+ <li><a href="#">Another action</a></li>
65
+ <li><a href="#">Something else here</a></li>
66
+ <li class="divider"></li>
67
+ <li class="dropdown-header">Nav header</li>
68
+ <li><a href="#">Separated link</a></li>
69
+ <li><a href="#">One more separated link</a></li>
70
+ </ul>
71
+ </li>
72
+ </ul>
73
+ <ul class="nav navbar-nav navbar-right">
74
+ <li><a href="../navbar/">Default</a></li>
75
+ <li><a href="../navbar-static-top/">Static top</a></li>
76
+ <li class="active"><a href="./">Fixed top</a></li>
77
+ </ul>
78
+ </div>
79
+ <!--/.nav-collapse -->
80
+ </div>
81
+ </div>
82
+
83
+ <div class="container">
84
+
85
+ <!-- Main component for a primary marketing message or call to action -->
86
+ <div class="jumbotron">
87
+ <h1>Cucumber step statistics</h1>
88
+
89
+ <p>... allows you to easily diagnose long running steps.</p>
90
+ </div>
91
+
92
+ <!--
93
+ step
94
+ fastest
95
+ slowest
96
+ variation
97
+ variance
98
+ standard_deviation
99
+ count
100
+ average
101
+ total
102
+ -->
103
+ <table class="table table-bordered table-striped sortable">
104
+ <thead>
105
+ <tr>
106
+ <th>Step</th>
107
+ <th>Fastest</th>
108
+ <th>Slowest</th>
109
+ <th>Variation</th>
110
+ <th>Variance</th>
111
+ <th>Std Deviation</th>
112
+ <th>Count</th>
113
+ <th>Average</th>
114
+ <th data-defaultsort="desc">Total</th>
115
+ </tr>
116
+
117
+ </thead>
118
+ <tbody>
119
+ <tr>
120
+ <td>/^I am logged in as ((?:(?:)|(?:(?:a|an|another|the|that) )?(?:(?:(?:(?:first|last|(?:\d+(?:st|nd|rd|th))) )?(?:paper[_ ]trail[_ ]version|acts[_ ]as[_ ]taggable[_ ]on[_ ]tag|acts[_ ]as[_ ]taggable[_ ]on[_ ]tagging|user|active[_ ]record[_ ]schema[_ ]migration|plan|feature|reference[_ ]type|allergy|relationship[_ ]type|allergy[_ ]type|medical[_ ]condition[_ ]type|account|rspec[_ ]account|address|sacred[_ ]heart[_ ]address|calendar[_ ]item|catalog|child|jack|jennifer[_ ]dillon|coupon|employment|enrollment|medical[_ ]condition|membership|organization|sacredheart|participation|person|sacredheart[_ ]person|bob|perry|carla|jordan|alienfast|alienfast[_ ]person|blake|kevin|alicia|product|relationship|subscription|rspec[_ ]subscription|tenant|transaction|admin|admin[_ ]not[_ ]owner|staff|consumer|consumer[_ ]dad|support|bmcdaniel|kross|awaters|verification))|(?:(?:paper[_ ]trail[_ ]version|acts[_ ]as[_ ]taggable[_ ]on[_ ]tag|acts[_ ]as[_ ]taggable[_ ]on[_ ]tagging|user|active[_ ]record[_ ]schema[_ ]migration|plan|feature|reference[_ ]type|allergy|relationship[_ ]type|allergy[_ ]type|medical[_ ]condition[_ ]type|account|rspec[_ ]account|address|sacred[_ ]heart[_ ]address|calendar[_ ]item|catalog|child|jack|jennifer[_ ]dillon|coupon|employment|enrollment|medical[_ ]condition|membership|organization|sacredheart|participation|person|sacredheart[_ ]person|bob|perry|carla|jordan|alienfast|alienfast[_ ]person|blake|kevin|alicia|product|relationship|subscription|rspec[_ ]subscription|tenant|transaction|admin|admin[_ ]not[_ ]owner|staff|consumer|consumer[_ ]dad|support|bmcdaniel|kross|awaters|verification)(?::? "(?:\\"|[^\"]|\.)*"))))) at (\w+)$/</td>
121
+ <td>7.051</td>
122
+ <td>4.099</td>
123
+ <td>4.099</td>
124
+ <td>0.320</td>
125
+ <td>0.566</td>
126
+ <td>76</td>
127
+ <td>0.490</td>
128
+ <td>37.288</td>
129
+ </tr>
130
+ <tr>
131
+ <td>/^Blah I am logged in as ((?:(?:)|(?:(?:a|an|another|the|that) )?(?:(?:(?:(?:first|last|(?:\d+(?:st|nd|rd|th))) )?(?:paper[_ ]trail[_ ]version|acts[_ ]as[_ ]taggable[_ ]on[_ ]tag|acts[_ ]as[_ ]taggable[_ ]on[_ ]tagging|user|active[_ ]record[_ ]schema[_ ]migration|plan|feature|reference[_ ]type|allergy|relationship[_ ]type|allergy[_ ]type|medical[_ ]condition[_ ]type|account|rspec[_ ]account|address|sacred[_ ]heart[_ ]address|calendar[_ ]item|catalog|child|jack|jennifer[_ ]dillon|coupon|employment|enrollment|medical[_ ]condition|membership|organization|sacredheart|participation|person|sacredheart[_ ]person|bob|perry|carla|jordan|alienfast|alienfast[_ ]person|blake|kevin|alicia|product|relationship|subscription|rspec[_ ]subscription|tenant|transaction|admin|admin[_ ]not[_ ]owner|staff|consumer|consumer[_ ]dad|support|bmcdaniel|kross|awaters|verification))|(?:(?:paper[_ ]trail[_ ]version|acts[_ ]as[_ ]taggable[_ ]on[_ ]tag|acts[_ ]as[_ ]taggable[_ ]on[_ ]tagging|user|active[_ ]record[_ ]schema[_ ]migration|plan|feature|reference[_ ]type|allergy|relationship[_ ]type|allergy[_ ]type|medical[_ ]condition[_ ]type|account|rspec[_ ]account|address|sacred[_ ]heart[_ ]address|calendar[_ ]item|catalog|child|jack|jennifer[_ ]dillon|coupon|employment|enrollment|medical[_ ]condition|membership|organization|sacredheart|participation|person|sacredheart[_ ]person|bob|perry|carla|jordan|alienfast|alienfast[_ ]person|blake|kevin|alicia|product|relationship|subscription|rspec[_ ]subscription|tenant|transaction|admin|admin[_ ]not[_ ]owner|staff|consumer|consumer[_ ]dad|support|bmcdaniel|kross|awaters|verification)(?::? "(?:\\"|[^\"]|\.)*"))))) at (\w+)$/</td>
132
+ <td>4.051</td>
133
+ <td>8.099</td>
134
+ <td>5.099</td>
135
+ <td>0.420</td>
136
+ <td>0.966</td>
137
+ <td>6</td>
138
+ <td>1.490</td>
139
+ <td>31.288</td>
140
+ </tr>
141
+ </tbody>
142
+ </table>
143
+
144
+ </div>
145
+ <!-- /container -->
146
+
147
+
148
+ <!-- Bootstrap core JavaScript
149
+ ================================================== -->
150
+ <!-- Placed at the end of the document so the pages load faster -->
151
+ <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script>
152
+ <script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
153
+ <script src="https://raw.githack.com/drvic10k/bootstrap-sortable/master/Scripts/moment.min.js"></script>
154
+ <script src="https://raw.githack.com/drvic10k/bootstrap-sortable/master/Scripts/bootstrap-sortable.js"></script>
155
+ <script type="text/javascript">
156
+ // Initialise on DOM ready
157
+ $(function() {
158
+ $.bootstrapSortable(true, 'reversed');
159
+ });
160
+ </script>
161
+ </body>
162
+ </html>
@@ -0,0 +1,145 @@
1
+ !!!
2
+ %html{:lang => "en"}
3
+ %head
4
+ %meta{:charset => "utf-8"}/
5
+ %meta{:content => "IE=edge", "http-equiv" => "X-UA-Compatible"}/
6
+ %meta{:content => "width=device-width, initial-scale=1", :name => "viewport"}/
7
+ %meta{:content => "Cucumber Step Statistics", :name => "description"}/
8
+ %meta{:content => "AlienFast", :name => "author"}/
9
+ %title Cucumber Step Statistics
10
+ / Bootstrap core CSS
11
+ %link{:href => "http://netdna.bootstrapcdn.com/bootstrap/3.1.1/css/bootstrap.min.css", :rel => "stylesheet"}/
12
+ / Custom styles for this layout
13
+ :css
14
+ body {
15
+ min-height: 2000px;
16
+ padding-top: 70px;
17
+ }
18
+
19
+ td {
20
+ white-space: nowrap;
21
+ /*max-width: 100px;*/
22
+ }
23
+ tr td:first-child {
24
+ overflow: hidden;
25
+ text-overflow: ellipsis;
26
+ max-width: 300px;
27
+ }
28
+ %link{:href => "https://raw.githack.com/drvic10k/bootstrap-sortable/master/Contents/bootstrap-sortable.css", :rel => "stylesheet"}/
29
+ / HTML5 shim and Respond.js IE8 support of HTML5 elements and media queries
30
+ /[if lt IE 9]
31
+ <script src="https://oss.maxcdn.com/libs/html5shiv/3.7.0/html5shiv.js"></script>
32
+ <script src="https://oss.maxcdn.com/libs/respond.js/1.4.2/respond.min.js"></script>
33
+ %body
34
+ / Fixed navbar
35
+ .navbar.navbar-default.navbar-fixed-top{:role => "navigation"}
36
+ .container
37
+ .navbar-header
38
+ %button.navbar-toggle{"data-target" => ".navbar-collapse", "data-toggle" => "collapse", :type => "button"}
39
+ %span.sr-only Toggle navigation
40
+ %span.icon-bar
41
+ %span.icon-bar
42
+ %span.icon-bar
43
+ %a.navbar-brand{:href => "#"} cucumber_statistics
44
+ .navbar-collapse.collapse
45
+ -#%ul.nav.navbar-nav
46
+ %li.active
47
+ %a{:href => "#"} Home
48
+ %li
49
+ %a{:href => "#about"} About
50
+ %li
51
+ %a{:href => "#contact"} Contact
52
+ %li.dropdown
53
+ %a.dropdown-toggle{"data-toggle" => "dropdown", :href => "#"}
54
+ Dropdown
55
+ %b.caret
56
+ %ul.dropdown-menu
57
+ %li
58
+ %a{:href => "#"} Action
59
+ %li
60
+ %a{:href => "#"} Another action
61
+ %li
62
+ %a{:href => "#"} Something else here
63
+ %li.divider
64
+ %li.dropdown-header Nav header
65
+ %li
66
+ %a{:href => "#"} Separated link
67
+ %li
68
+ %a{:href => "#"} One more separated link
69
+ %ul.nav.navbar-nav.navbar-right
70
+ -#%li
71
+ -# %a{:href => "../navbar/"} Default
72
+ -#%li
73
+ -# %a{:href => "../navbar-static-top/"} Static top
74
+ %li
75
+ %a{:href => "https://github.com/alienfast/cucumber_statistics", :target => 'other'} Github
76
+ / /.nav-collapse
77
+ .container
78
+ / Main component for a primary marketing message or call to action
79
+ .jumbotron
80
+ %h1 Cucumber step statistics
81
+ %p ... allows you to easily diagnose long running steps.
82
+
83
+ .alert.alert-info
84
+ %span
85
+ #{overall_statistics.feature_count} Features,
86
+ #{overall_statistics.scenario_count} Scenario,
87
+ #{overall_statistics.step_count} Steps completed in #{format(overall_statistics.duration)}.
88
+ %span.text-muted.pull-right.small
89
+ Finished on #{format_date_time(overall_statistics.end_time)}
90
+
91
+ %table.table.table-bordered.table-striped.sortable
92
+ %thead
93
+ %tr
94
+ %th Step
95
+ %th Fastest
96
+ %th Slowest
97
+ %th Variation
98
+ %th Variance
99
+ %th Std Deviation
100
+ %th Count
101
+ %th Average
102
+ %th{"data-defaultsort" => "desc"} Total
103
+ %tbody
104
+
105
+ - highest_average = step_statistics.highest_average
106
+ - highest_total = step_statistics.highest_total
107
+ - highest_variation = step_statistics.highest_variation
108
+
109
+
110
+ - step_statistics.all.each do |step_results|
111
+
112
+ %tr
113
+ = name_td step_results
114
+ = time_td step_results, :fastest
115
+ = time_td step_results, :slowest
116
+ = time_td step_results, :variation, highest_variation
117
+ = time_td step_results, :variance
118
+ = time_td step_results, :standard_deviation
119
+ = count_td step_results, :count
120
+ = time_td step_results, :average, highest_average
121
+ = time_td step_results, :total, highest_total
122
+ -#%tr
123
+ %td /^Blah I am logged in as ((?:(?:)|(?:(?:a|an|another|the|that) )?(?:(?:(?:(?:first|last|(?:\d+(?:st|nd|rd|th))) )?(?:paper[_ ]trail[_ ]version|acts[_ ]as[_ ]taggable[_ ]on[_ ]tag|acts[_ ]as[_ ]taggable[_ ]on[_ ]tagging|user|active[_ ]record[_ ]schema[_ ]migration|plan|feature|reference[_ ]type|allergy|relationship[_ ]type|allergy[_ ]type|medical[_ ]condition[_ ]type|account|rspec[_ ]account|address|)(?::? "(?:\\"|[^\"]|\.)*"))))) at (\w+)$/
124
+ %td 4.051
125
+ %td 8.099
126
+ %td 5.099
127
+ %td 0.420
128
+ %td 0.966
129
+ %td 6
130
+ %td 1.490
131
+ %td 31.288
132
+ / /container
133
+ /
134
+ Bootstrap core JavaScript
135
+ \==================================================
136
+ / Placed at the end of the document so the pages load faster
137
+ %script{:src => "https://ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"}
138
+ %script{:src => "http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"}
139
+ %script{:src => "https://raw.githack.com/drvic10k/bootstrap-sortable/master/Scripts/moment.min.js"}
140
+ %script{:src => "https://raw.githack.com/drvic10k/bootstrap-sortable/master/Scripts/bootstrap-sortable.js"}
141
+ :javascript
142
+ // Initialise on DOM ready
143
+ $(function() {
144
+ $.bootstrapSortable(true, 'reversed');
145
+ });
data/notes.txt ADDED
@@ -0,0 +1,9 @@
1
+ http://www.oesmith.co.uk/morris.js/lines.html
2
+ http://drvic10k.github.io/bootstrap-sortable/
3
+
4
+ http://stackoverflow.com/questions/6125265/using-layouts-in-haml-files-independently-of-rails
5
+ http://getbootstrap.com/examples/navbar-fixed-top/
6
+
7
+
8
+ Total time of run
9
+ file path/name/line number of step
@@ -0,0 +1,20 @@
1
+ require 'spec_helper'
2
+
3
+ module CucumberStatistics
4
+ describe Configuration do
5
+
6
+ before do
7
+ Configuration.clean_tmp_dir
8
+ end
9
+
10
+ it 'should auto create tmp_dir' do
11
+
12
+ tmp_dir = Configuration.tmp_dir
13
+ Dir.exists?(tmp_dir).should == true
14
+
15
+ Dir.delete tmp_dir
16
+ tmp_dir = Configuration.tmp_dir
17
+ Dir.exists?(tmp_dir).should == true
18
+ end
19
+ end
20
+ end