在过去的两年里,我在一些项目中使用TDD作为开发风格,但我总是陷入同样的困境:如何测试程序各个部分的集成?
我目前正在做的是为每个类编写一个测试用例(这是我的经验法则:"单元"是一个类,每个类都有一个或多个测试用例).我尝试通过使用模拟和存根来解决依赖关系,这非常有效,因为每个类都可以独立测试.经过一些编码后,所有重要的类都会进行测试 然后我使用IoC容器将它们"连接"在一起.在这里,我陷入困境:如何测试布线是否成功,对象是否按照我想要的方式进行交互?
一个例子:想想一个Web应用程序.有一个控制器类,它接受一组id,使用存储库根据这些ID获取记录,然后迭代记录并将它们作为字符串写入outfile.
为简单起见,将有三类:Controller,Repository,OutfileWriter.他们每个人都是孤立地进行测试.
我将做什么来测试"真正的"应用程序:使用数据库中的一些ID发出http请求(手动或自动),然后查看文件系统是否写入文件.当然,这个过程可以自动化,但仍然是:它不会复制测试逻辑吗?这是所谓的"集成测试"吗?在我最近阅读的关于单元测试的一本书中,在我看来,集成测试更像是一种反模式?
因此,以这个 html 为例:
<ul>
<li>
<a href="#">Test</a>
<ul>
<li><a href="#">Test</a></li>
<li><a href="#">Test</a></li>
<li><a href="#">Test</a></li>
<li><a href="#">Test</a></li>
</ul>
</li>
<li>
<a href="#">Test</a>
<ul>
<li><a href="#">Test</a></li>
<li>
<a href="#">Test</a>
<ul>
<li><a href="#">Test</a></li>
<li><a href="#">Test</a></li>
<li><a href="#">Test</a></li>
<li><a href="#">Test</a></li>
</ul>
</li>
</ul>
</li>
</ul>
Run Code Online (Sandbox Code Playgroud)
我想找出这个结构的最大深度,在这个例子中它是 3,因为结构向下 3 层。但是该结构可以具有任意深度。
使用 DOM 扩展的 javascript/jquery 解决方案或基于 PHP 的解决方案都可以。我真的想不出有什么好的方法可以做到这一点。也许有一个 xpath 表达式完全符合我的要求?
编辑:澄清:在这种情况下,深度是ul元素的最大嵌套,在这种情况下为 3。
我使用express/formidable在node.js中创建了一个上传脚本.它基本上有效,但我想知道在何时何地检查上传的文件,例如最大文件大小或文件的mimetype是否实际允许.
我的程序看起来像这样:
app.post('/', function(req, res, next) {
req.form.on('progress', function(bytesReceived, bytesExpected) {
// ... do stuff
});
req.form.complete(function(err, fields, files) {
console.log('\nuploaded %s to %s', files.image.filename, files.image.path);
// ... do stuff
});
});
Run Code Online (Sandbox Code Playgroud)
在我看来,检查mimetype /文件大小的唯一可行的地方是complete我可以可靠地使用文件系统函数来获取上传文件大小的事件/tmp/- 但这似乎不是一个好主意,因为:
什么是实施这个的最佳实践?我在node.js中找到了很多文件上传的例子,但似乎没有人做我需要的安全检查.
我对这段代码感到有点困惑.
public static void Foo(A p)
{
p.SomeProp = "ccc";
p = null; // !!!
}
static void Main(string[] args)
{
A p = new A();
Foo(p);
Console.WriteLine("SomeProp is: " + p.SomeProp);
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
输出是:
"SomeProp是:ccc "
但我本来期望一个NullReferenceException.
但是,如果我这样更改它,使用ref修饰符:
public static void Foo(ref A p)
{
p.SomeProp = "ccc";
p = null;
}
static void Main(string[] args)
{
A p = new A();
Foo(ref p);
Console.WriteLine("SomeProp is: " + p.SomeProp);
Console.ReadLine();
}
Run Code Online (Sandbox Code Playgroud)
我得到一个NullReferenceException - 第二个对我来说是可以理解的.
但是怎么可能,在第一段代码中p没有设置为null,但属性是否设置了它的值?
我的问题是:如果它不是对原始实例的引用,那么第一段代码中Foo方法的p参数是什么?
顺便说一句.这是A类的定义
public class …Run Code Online (Sandbox Code Playgroud) 在我的C程序中,我使用了libcurl的一些基本功能.今天我跑了valgrind,以检查我是否有内存泄漏,valgrind疯狂报告多个错误.
我跟踪它基本上是:
CURL *curl;
CURLcode res;
curl = curl_easy_init();
// ...
curl_easy_cleanup(curl);
Run Code Online (Sandbox Code Playgroud)
如果我完全删除使用libcurl的代码,valgrind不会报告任何错误.
我已经读过使用valgrind与libcurl和ssl有一些问题,但是我不提取任何https网址等.
我能做什么?我可以让valgrind关闭libcurl错误(可能是误报吗?)并仅报告我的代码中的错误?尽管libcurl的使用最简单,但由于存在大量错误,因此valgrind的输出非常混乱.
不幸的是我没有安装libcurl构建的调试,所以valgrind甚至不报告它检测到泄漏的行号/文件.错误消息如下所示:
==27330==
==27330== HEAP SUMMARY:
==27330== in use at exit: 34,960 bytes in 2,406 blocks
==27330== total heap usage: 20,130 allocs, 17,724 frees, 2,511,576 bytes allocated
==27330==
==27330== 40 (20 direct, 20 indirect) bytes in 1 blocks are definitely lost in loss record 383 of 445
==27330== at 0x4025BD3: malloc (vg_replace_malloc.c:236)
==27330== by 0x4B173FD: ???
==27330== by 0x4B17A8B: ???
==27330== by 0x4B84957: ???
==27330== by …Run Code Online (Sandbox Code Playgroud) 我有这个功能,它对某个年龄组中用户的年龄进行分类:
private function calculateAgeGroup($age)
{
if (!$age) {
return null;
}
if ($age <= 25) {
return '0-25';
}
if ($age <= 30) {
return '26-30';
}
if ($age <= 35) {
return '31-35';
}
if ($age <= 40) {
return '36-40';
}
if ($age <= 45) {
return '41-45';
}
if ($age <= 50) {
return '46-50';
}
if ($age <= 60) {
return '51-60';
}
return '61-';
}
Run Code Online (Sandbox Code Playgroud)
有没有办法简化(意思是:更简洁,更少的陈述)这个?我的第一个想法是关于使用modulo,但我很快就认为它很快,因为在这里使用modulo是没有意义的.
第二种选择是类似的,floor($age/10)*10 . "-" . ceil($age/10)*10但在所有情况下都不起作用.
我想到的最后一个选项是使用一系列() …
我有一个这样的示例程序:
#include <stdio.h>
#if 1
#define FOR_EXPORT __attribute__ ((visibility("hidden")))
#else
#define FOR_EXPORT
#endif
FOR_EXPORT void mylocalfunction1(void)
{
printf("function1\n");
}
void mylocalfunction2(void)
{
printf("function2\n");
}
void mylocalfunction3(void)
{
printf("function3\n");
}
void printMessage(void)
{
printf("Running the function exported from the shared library\n");
}
Run Code Online (Sandbox Code Playgroud)
并使用编译它
gcc -shared -fPIC -fvisibility=hidden -o libdefaultvisibility.so defaultvisibility.c
Run Code Online (Sandbox Code Playgroud)
现在编译完成后我做了:
$ nm libdefaultvisibility.so
nm libdefaultvisibility.so
0000000000000eb0 t _mylocalfunction1
0000000000000ed0 t _mylocalfunction2
0000000000000ef0 t _mylocalfunction3
0000000000000f10 t _printMessage
U _printf
U dyld_stub_binder
Run Code Online (Sandbox Code Playgroud)
这意味着尽管-fvisibility=hidden所有符号都被导出,但据我所知.我所遵循的这本书声称只有标记的功能FOR_EXPORT才能导出.
我看了几个其他资源,但对于我正在做的简单测试-fvisibility=hidden应该足够了.
我的铿锵版: …
我试图通过指针算法迭代结构数组.然而它给了我无法理解的结果.
#include <stdio.h>
#include <stdlib.h>
typedef struct
{
int hours;
int minutes;
int seconds;
} Time;
void time_print(Time t)
{
printf("Time is: %d:%d:%d\n", t.hours, t.minutes, t.seconds);
}
int main(void)
{
Time *testTimePointers[2];
testTimePointers[0] = malloc(sizeof(Time));
testTimePointers[0]->hours = 11;
testTimePointers[0]->minutes = 10;
testTimePointers[0]->seconds = 9;
testTimePointers[1] = malloc(sizeof(Time));
testTimePointers[1]->hours = 7;
testTimePointers[1]->minutes = 6;
testTimePointers[1]->seconds = 5;
time_print(*(testTimePointers[0]));
time_print(*(testTimePointers[1]));
printf("=============\n");
Time *ttp_cur = NULL;
ttp_cur = testTimePointers[0];
time_print(*(ttp_cur));
ttp_cur++;
time_print(*(ttp_cur));
free(testTimePointers[0]);
free(testTimePointers[1]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
结果是
Time is: 11:10:9
Time is: …Run Code Online (Sandbox Code Playgroud) 我基本上要做的是模糊图像,并将其与原始图像组合在一起,这样原始图像中的某些区域才会模糊(脸部应该模糊).
我的一般想法是掩盖原始Iwant中的部分模糊,然后将原始模糊为副本并再次将它们"合并"在一起.
在某种程度上,这也有效.
我的图片:
我的C++代码创建这些图像:
int main(void) {
cv::Mat srcImage = cv::imread(path);
srcImage.convertTo(srcImage, CV_32FC3, 1.0/255.0);
Mat _mask;
Mat img_gray;
cv::Scalar white = cv::Scalar(255, 255, 255);
cv::Scalar black = cv::Scalar(0, 0, 0);
cv::cvtColor(srcImage, img_gray, cv::COLOR_BGR2GRAY);
img_gray.convertTo(_mask, CV_32FC1);
// face
cv::circle(_mask, cv::Point(430, 350), 200, black, -1, 8, 0);
// eyes
cv::circle(_mask, cv::Point(502, 260), 27, white, -1, 8, 0);
cv::circle(_mask, cv::Point(390, 260), 27, white, -1, 8, 0);
// mouth
cv::ellipse(_mask, cv::Point(440, 390), cv::Point(60, 25), 0, 0, 360, white, -1, 8, …Run Code Online (Sandbox Code Playgroud) 我开始将我的一个项目的代码分组到模块文件中。我遇到了很多关于这些模块中函数未使用代码的警告,但这些函数实际上已被使用(在模块内私有)。
我的项目的一个例子:
// ...
// Line 46:
fn calc_p(word: &str, dict: &Dictionary) -> f32
{
if !dict.contains_key(word) {
return 0.0;
}
let total: u32 = dict.values().sum();
dict[word] as f32 / total as f32
}
...
Run Code Online (Sandbox Code Playgroud)
但在同一文件、同一模块的第 13 行,该函数显然被使用了:
// ...
pub fn suggest_corrections(to_be_corrected: &str, dict: &Dictionary) -> Vec<(f32, String)>
{
let candidates = create_candidates(to_be_corrected, dict);
let mut weighted_candidates = candidates
.into_iter()
.map(|w| (calc_p(&w, dict), w)) // Line 13 - calc_p used here
.collect::<Vec<_>>();
weighted_candidates.sort_by(|a, b| b.partial_cmp(a).unwrap());
weighted_candidates …Run Code Online (Sandbox Code Playgroud) c ×3
php ×2
arrays ×1
c# ×1
c++ ×1
clang ×1
code-cleanup ×1
file-upload ×1
jquery ×1
libcurl ×1
linker ×1
memory-leaks ×1
node.js ×1
opencv ×1
rust ×1
struct ×1
unit-testing ×1
valgrind ×1