cucumber_statistics 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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